org.kepler.objectmanager.ObjectManager.java Source code

Java tutorial

Introduction

Here is the source code for org.kepler.objectmanager.ObjectManager.java

Source

/*
 * Copyright (c) 2009-2010 The Regents of the University of California.
 * All rights reserved.
 *
 * '$Author: aschultz $'
 * '$Date: 2011-03-02 11:59:11 -0800 (Wed, 02 Mar 2011) $' 
 * '$Revision: 27233 $'
 * 
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the above
 * copyright notice and the following two paragraphs appear in all copies
 * of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS.
 *
 */

package org.kepler.objectmanager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kepler.moml.NamedObjId;
import org.kepler.objectmanager.cache.CacheException;
import org.kepler.objectmanager.cache.CacheManager;
import org.kepler.objectmanager.cache.CacheObject;
import org.kepler.objectmanager.cache.CacheObjectInterface;
import org.kepler.objectmanager.lsid.KeplerLSID;

import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.NamedObj;

/**
 * The ObjectManager searches through all of the NamedObj Objects in the
 * workspace to see if any of them have a KeplerLSID associated with them.
 * 
 * @author Aaron Schultz
 * @version $Id: ObjectManager.java 27233 2011-03-02 19:59:11Z aschultz $
 * 
 */
public class ObjectManager {

    private static final Log log = LogFactory.getLog(ObjectManager.class.getName());
    private static final boolean isDebugging = log.isDebugEnabled();

    // WeakHashMap will discard items required during KAR save process
    // (refactored so this is probably only the workflow now).
    // see: http://bugzilla.ecoinformatics.org/show_bug.cgi?id=5200
    //private WeakHashMap<KeplerLSID, NamedObj> _namedObjs;
    private Map<KeplerLSID, NamedObj> _namedObjs;

    /**
     * Empty constructor
     */
    public ObjectManager() {
        //_namedObjs = new WeakHashMap<KeplerLSID, NamedObj>(1);
        HashMap<KeplerLSID, NamedObj> hashMap = new HashMap<KeplerLSID, NamedObj>(1);
        _namedObjs = Collections.synchronizedMap(hashMap);
    }

    /**
     * Add a NamedObject to the ObjectManager. These are searched when getting
     * an object by LSID.
     * 
     * @param namedObj
     * @throws Exception
     */
    public void addNamedObj(NamedObj namedObj) throws Exception {
        KeplerLSID lsid = NamedObjId.getIdFor(namedObj);
        //Set<KeplerLSID> keys = _namedObjs.keySet();
        //Collection<NamedObj> values = _namedObjs.values();
        if (_namedObjs.containsKey(lsid)) {
            _namedObjs.remove(lsid);
        }
        _namedObjs.put(lsid, namedObj);
    }

    /**
     * Attempt to remove NamedObj from ObjectManager: 
     * if getIdFor(namedObj) returns an LSID for an object 
     * in the ObjectManager, it will be removed.
     * 
     * @param namedObj
     * @return removed NamedObj, or null if none.
     */
    public NamedObj removeNamedObj(NamedObj namedObj) {
        KeplerLSID lsid = NamedObjId.getIdFor(namedObj);
        return _namedObjs.remove(lsid);
    }

    /**
     * Attempt to remove NamedObj from ObjectManager: 
     * if getIdFor(namedObj) returns an LSID for an object 
     * in the ObjectManager, it will be removed.
     * 
     * @param namedObj
     * @return removed NamedObj, or null if none.
     */
    public ArrayList<NamedObj> removeNamedObjs(NamedObj namedObj) {
        KeplerLSID lsid = NamedObjId.getIdFor(namedObj);
        //it is modified because of bug // http://bugzilla.ecoinformatics.org/show_bug.cgi?id=5095#c14
        // the reason is because the lsid of an updated namedObj is changed, the old method won't remove the old versions of namedObj.
        //return _namedObjs.remove(lsid);
        return removeObjectsForLSIDWithoutRevision(lsid.toStringWithoutRevision());
    }

    /**
     * Attempts to remove object from ObjectManager: 
     * if getObjectRevision(lsid) returns a NamedObj, calls removeNamedObj on
     * this NamedObj.
     * 
     * NOTE: Chances are good this won't remove the NamedObj you want.
     * 
     * @param lsid
     * @return removed NamedObj, or null if none.
     * @throws Exception
     */
    public NamedObj removeObject(KeplerLSID lsid) throws Exception {
        if (isDebugging)
            log.debug("removeObject(" + lsid + ")");
        NamedObj no = getObjectRevision(lsid);
        if (no != null) {
            return removeNamedObj(no);
        }
        return null;
    }

    /**
     * @param lsid for the NamedObj to remove from ObjectManager
     * @return the NamedObj removed, or null if none.
     */
    public NamedObj removeObjectForLSID(KeplerLSID lsid) {
        return _namedObjs.remove(lsid);
    }

    /**
     * Remove all NamedObjects from ObjectManager that match this lsid without
     * revision.
     * @param lsidWithoutRevision
     * @return ArrayList of NamedObjs that were removed.
     */
    public ArrayList<NamedObj> removeObjectsForLSIDWithoutRevision(String lsidWithoutRevision) {
        ArrayList<NamedObj> removedNamedObjects = new ArrayList<NamedObj>();
        Iterator<KeplerLSID> lsidItr = _namedObjs.keySet().iterator();
        ArrayList<KeplerLSID> lsidsToRemove = new ArrayList<KeplerLSID>();
        while (lsidItr.hasNext()) {
            KeplerLSID lsid = lsidItr.next();
            if (lsid.toStringWithoutRevision().equals(lsidWithoutRevision)) {
                lsidsToRemove.add(lsid);
            }
        }

        lsidItr = lsidsToRemove.iterator();
        while (lsidItr.hasNext()) {
            KeplerLSID lsid = lsidItr.next();
            NamedObj removedNamedObj = _namedObjs.remove(lsid);
            removedNamedObjects.add(removedNamedObj);
        }

        return removedNamedObjects;
    }

    /**
     * 
     * @param lsid
     * @return
     * @throws Exception
     */
    public String getObjectType(KeplerLSID lsid) throws Exception {
        if (isDebugging)
            log.debug("getObjectType(" + lsid + ")");
        NamedObj no = getObjectRevision(lsid);
        if (no == null) {
            return null;
        }
        return no.getClass().getName();
    }

    /**
     * 
     * @param lsid
     * @return
     * @throws Exception
     */
    public NamedObj getObjectRevision(KeplerLSID lsid) throws Exception {
        if (isDebugging) {
            log.debug("getObjectRevision(" + lsid + ")");
            printDebugInfo();
        }

        boolean matchRevision = true;

        NamedObj obj = getObjectFromManager(lsid, matchRevision);
        if (obj == null) {
            if (isDebugging)
                log.debug(lsid + " is not registered with ObjectManager");
            obj = getObjectFromCache(lsid);
            if (obj == null) {
                if (isDebugging)
                    log.debug(lsid + " is not registered with CacheManager");
            }
        }

        if (obj != null) {
            if (isDebugging)
                log.debug(obj.getName() + " was found");
            // Make sure it has the NamedObjId Attribute
            NamedObjId noi = NamedObjId.getIdAttributeFor(obj);
            if (noi == null) {
                NamedObjId lsidSA = new NamedObjId(obj, NamedObjId.NAME);
                lsidSA.setExpression(lsid.toString());
            } else {
                KeplerLSID lsidCheck = noi.getId();
                if (!lsidCheck.equals(lsid)) {
                    log.error("lsids don't match: " + lsid.toString() + " != " + lsidCheck);
                    noi.setExpression(lsid.toString());
                }
            }
        }

        return obj;
    }

    /**
     * Return the NamedObj that has the highest revision number for a given LSID
     * after searching through all the NamedObjs accessible by the
     * ObjectManager. If no NamedObj is found at all then try to get the highest
     * revision from the cache. If that doesn't find anything then return null.
     * This method will replace the existing getObject(KeplerLSID) method
     * 
     * @param lsid
     * @return
     * @throws Exception
     */
    public NamedObj getHighestObjectRevision(KeplerLSID lsid) throws Exception {
        boolean matchRevision = false;

        Vector<NamedObj> allObjs = new Vector<NamedObj>();

        for (NamedObj namedObj : _namedObjs.values()) {
            if (namedObj instanceof CompositeEntity) {
                Vector<NamedObj> theNOS = findAll(lsid, (CompositeEntity) namedObj, matchRevision);

                if (theNOS != null) {
                    for (NamedObj no : theNOS) {
                        allObjs.add(no);
                    }
                }
            } else {
                if (NamedObjId.idMatches(lsid, namedObj, matchRevision)) {
                    allObjs.add(namedObj);
                }
            }
        }

        NamedObj noWithHighestLSID = null;
        for (NamedObj no : allObjs) {
            if (noWithHighestLSID == null) {
                noWithHighestLSID = no;
            } else {
                NamedObjId idAtt = NamedObjId.getIdAttributeFor(no);
                if (idAtt != null) {
                    KeplerLSID objId = idAtt.getId();

                    NamedObjId noWithHighestIdAtt = NamedObjId.getIdAttributeFor(noWithHighestLSID);
                    KeplerLSID noWithHighestObjId = noWithHighestIdAtt.getId();

                    if (objId.getRevision() > noWithHighestObjId.getRevision()) {
                        noWithHighestLSID = no;
                    }
                }
            }
        }

        if (noWithHighestLSID == null) {
            // get the highest revision from the CacheManager
            try {
                CacheObject co = CacheManager.getInstance().getHighestCacheObjectRevision(lsid);
                if (co != null) {
                    Object o = co.getObject();
                    if (o instanceof NamedObj) {
                        noWithHighestLSID = (NamedObj) o;
                    }
                }
            } catch (CacheException ce) {
                ce.printStackTrace();
            }

        }

        return noWithHighestLSID;
    }

    /**
     * Return all of the NamedObjs contained by the given CompositeEntity that
     * match the given lsid either with or without matching the revision as
     * specified.
     * 
     * @param lsid
     * @param composite
     * @param matchRevision
     * @return
     */
    private Vector<NamedObj> findAll(KeplerLSID lsid, CompositeEntity composite, boolean matchRevision) {
        Vector<NamedObj> objs = new Vector<NamedObj>(3);

        if (NamedObjId.idMatches(lsid, (NamedObj) composite, matchRevision)) {
            objs.add((NamedObj) composite);
        }

        for (Object obj : composite.entityList()) {
            if (obj instanceof NamedObj) {
                if (NamedObjId.idMatches(lsid, (NamedObj) obj, matchRevision)) {
                    objs.add((NamedObj) obj);
                }
                if (obj instanceof CompositeEntity) {
                    Vector<NamedObj> childObjs = findAll(lsid, (CompositeEntity) obj, matchRevision);
                    if (childObjs != null && childObjs.size() > 0) {
                        for (NamedObj o : childObjs) {
                            objs.add(o);
                        }
                    }
                }
            }
        }

        if (objs.size() > 0) {
            return objs;
        }
        return null;
    }

    /**
     * Return a NamedObj that has been added to the ObjectManager.
     * 
     * @param lsid
     * @return
     * @throws Exception
     */
    private NamedObj getObjectFromManager(KeplerLSID lsid, boolean matchRevision) throws Exception {
        if (isDebugging)
            log.debug("getObjectFromManager(" + lsid + "," + matchRevision + ")");
        for (NamedObj namedObj : _namedObjs.values()) {
            if (namedObj instanceof CompositeEntity) {
                NamedObj theNO = checkComposite(lsid, (CompositeEntity) namedObj, matchRevision);

                if (theNO != null) {
                    if (isDebugging)
                        log.debug("Found NamedObj: " + theNO.getName() + " " + NamedObjId.getIdFor(theNO));
                    return theNO;
                }
            } else {
                if (NamedObjId.idMatches(lsid, namedObj, matchRevision)) {
                    return namedObj;
                }
            }
        }
        return null;
    }

    /**
     * Return a NamedObj that has been instantiated from the CacheManager.
     * 
     * @param lsid
     * @return
     * @throws Exception
     */
    private NamedObj getObjectFromCache(KeplerLSID lsid) throws Exception {
        NamedObj obj = null;

        CacheObjectInterface coi = CacheManager.getInstance().getObject(lsid);
        if (coi != null) {
            if (isDebugging)
                log.debug("CacheObjectInterface found in CacheManager");
            Object o = coi.getObject();
            if (o != null) {
                if (isDebugging) {
                    log.debug(o.getClass().getName());
                }
                if (o instanceof NamedObj) {
                    obj = (NamedObj) o;
                } else if (o instanceof ActorMetadata) {
                    ActorMetadata am = (ActorMetadata) o;
                    obj = am.getActor();
                }
            }
        }
        return obj;

    }

    /**
     * Deeply recurse all entities of the given composite entity and return the
     * NamedObj that matches the search LSID
     */
    private NamedObj checkComposite(KeplerLSID lsid, CompositeEntity composite, boolean matchRevision) {
        if (isDebugging)
            log.debug("checkComposite(" + composite.getName() + ")");

        if (NamedObjId.idMatches(lsid, (NamedObj) composite, matchRevision)) {
            return (NamedObj) composite;
        }

        for (Object obj : composite.entityList()) {
            if (obj instanceof NamedObj) {
                if (isDebugging)
                    log.debug(((NamedObj) obj).getName());
                if (NamedObjId.idMatches(lsid, (NamedObj) obj, matchRevision)) {
                    return (NamedObj) obj;
                }
                if (obj instanceof CompositeEntity) {
                    NamedObj theObj = checkComposite(lsid, (CompositeEntity) obj, matchRevision);
                    if (theObj != null) {
                        return theObj;
                    }
                }
            }
        }
        return null;
    }

    /**
     * Print the objects that are currently registered with the ObjectManager.
     */
    public void printDebugInfo() {
        System.out.println("*************" + " NamedObjs registered with ObjectManager:");
        Iterator<KeplerLSID> lsidItr = _namedObjs.keySet().iterator();
        while (lsidItr.hasNext()) {
            KeplerLSID lsid = lsidItr.next();
            System.out.println(_namedObjs.get(lsid).getName() + "=>" + lsid);
        }

        System.out.println("** getIdFor these NamedObj returns:");
        for (NamedObj no : _namedObjs.values()) {
            System.out.println(no.getName() + " getIdFor(" + no.getName() + "):" + NamedObjId.getIdFor(no));
        }

        System.out.println("*************\n");

    }

    /**
     * Method for getting an instance of this singleton class.
     */
    public static ObjectManager getInstance() {
        return ObjectManagerHolder.INSTANCE;
    }

    private static class ObjectManagerHolder {
        private static final ObjectManager INSTANCE = new ObjectManager();
    }
}