Package org.objectweb.speedo.genclass.collection

Source Code of org.objectweb.speedo.genclass.collection.CollectionAccessor

/**
* Copyright (C) 2001-2004 France Telecom R&D
*
* 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 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
*/
package org.objectweb.speedo.genclass.collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.jdo.listener.DetachLifecycleListener;

import org.objectweb.jorm.api.PIndexedElem;
import org.objectweb.jorm.naming.api.PName;
import org.objectweb.jorm.util.api.Loggable;
import org.objectweb.speedo.api.Debug;
import org.objectweb.speedo.genclass.GenClassAccessor;
import org.objectweb.speedo.genclass.GenClassElement;
import org.objectweb.speedo.genclass.PIndexedElemIterator;
import org.objectweb.speedo.genclass.AbstractGenClassHome;
import org.objectweb.speedo.genclass.api.SpeedoGenClassPO;
import org.objectweb.speedo.mim.api.DetachedLifeCycle;
import org.objectweb.speedo.mim.api.LifeCycle;
import org.objectweb.speedo.mim.api.StateItf;
import org.objectweb.speedo.mim.api.PersistentObjectItf;
import org.objectweb.speedo.pm.api.POManagerItf;
import org.objectweb.util.monolog.api.BasicLevel;

/**
* @author  S.Chassande-Barrioz
*/
public class CollectionAccessor
        extends GenClassAccessor
        implements Collection {

  /**
   * is the internal collection used when the gen class is not active.
   * When the po is active the 'elements' field is used.
   */
  protected Collection collection = null;


    /**
     * Instanciates and initializes a new collection with an initial size.
     */
    public CollectionAccessor(SpeedoGenClassPO thepo) {
        super(thepo);
    collection = (Collection) gcpo.createGenClass();
    }

    public String toString() {
        return "CollectionAccessor: id=" + gcpo.speedoGetGenClassId();
    }

  protected boolean duplicatAllowed() {
    return true;
  }

  public GenClassElement speedoRemove2(Object o) {
    tmpelem.setElement(o);   // tmp type = etype.
    Iterator it = elements.iterator();
    while (it.hasNext()) {
      CollectionElem e = (CollectionElem) it.next();
      if (e.equals(tmpelem) && e.getElemStatus() != PIndexedElem.ELEM_DELETED) {
        e.setStatus(PIndexedElem.ELEM_DELETED);
        if (Debug.ON && getLogger() != null) {
          logger.log(BasicLevel.DEBUG, "speedoRemove2(): removed");
        }
        return e;
      }
    }
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "speedoRemove2(): not found");
    }
    return null;
  }

    public void makePersistent(POManagerItf pm) {
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "makePersistent");
    }
        if (collection.size() > 0) {
            ((AbstractGenClassHome) getSpeedoPO().speedoGetHome())
              .makePersistent(pm, collection.iterator(), null, null);
        }
    }
   
    public void makePersistentOnAttach(POManagerItf pm, Map map) {
      if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "makePersistent");
    }
        if (collection.size() > 0) {
            ((AbstractGenClassHome) getSpeedoPO().speedoGetHome())
              .makePersistent(pm, collection.iterator(), null, map);
        }
    }
   
  public void deletePersistent(POManagerItf pm) {
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "deletePersistent");
    }
    clear();
  }

  public void setElements(Object o) {
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "setElements()");
    }
    clear();
    if (o != null) {
      addAll(((Collection) o));
    }
  }

  public void loadFieldsFromAccessor(StateItf sa) {
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "jdoLoadFieldsFromAccessor()");
    }
    CollectionAccessor ca = (CollectionAccessor) sa;
    collection.clear();
    collection.addAll(ca.collection);
    supportDelta = ca.supportDelta;
    elements.clear();
    elements.addAll(ca.elements);
    speedoSetStatus(ca.speedoGetStatus());
  }

  public void detachCopy(POManagerItf pm, Map map, StateItf fieldsClone, Collection fgHints){
    ((CollectionAccessor)fieldsClone).loadFieldsFromAccessor(this);
    //copy the elements in the collection: collection is no more available when the po is not active
    ((CollectionAccessor)fieldsClone).collection.clear();
    //get an interator on the PIndexed elements
    Iterator it = ((GenClassAccessor) fieldsClone).elements.iterator();
    while(it.hasNext()){
      //for each element of the collection, send the list of fields to load passed as a parameter
      //indeed, the list sent will be modified (elements processed are removed)
      Iterator itFgHints = fgHints.iterator();
      Collection currentFgHints = new ArrayList();
      while (itFgHints.hasNext()) {
        currentFgHints.add((String)itFgHints.next());
      }
      //get the PIndexElement
      CollectionElem iElem = (CollectionElem) it.next();
      //get the object associated
      Object elem = iElem.getElement((POManagerItf) pm);
      Object clone = null;
      //if it is a persistent object, detach it
      if (elem instanceof PersistentObjectItf) {
        //get the speedo po associated
        PersistentObjectItf sp = (PersistentObjectItf) elem;
        if(map != null)
          clone = map.get(sp);
        //detach only if not already done before
        if (clone == null) {
          synchronized(currentFgHints){
            //get the clone of the speedo po 
            clone = pm.speedoDetachCopy(sp, map, currentFgHints);
          }
        }
      } else {
        //else, just copy it
        clone = elem;
      }
      //add the clone in the collection of elements reachable when the po is no more active
      ((CollectionAccessor)fieldsClone).collection.add(clone);
    }
    ((GenClassAccessor) fieldsClone).speedoSetStatus(LifeCycle.TRANSIENT);
  }
 
  public void attachCopy(POManagerItf pm, Map map, StateItf fieldsClone) {
    CollectionAccessor ca = (CollectionAccessor) fieldsClone;
    //get an iterator on the PIndexed elements of the collection
    Iterator it = ca.collection.iterator();
    while(it.hasNext()){
      Object elem = it.next();
      //if it is a persistent object
      if (elem instanceof PersistentObjectItf) {
        //get the detached speedo po
        PersistentObjectItf spDetached = (PersistentObjectItf) elem;
        PersistentObjectItf sp = (PersistentObjectItf) map.get(spDetached);
        if(sp == null){
          map.put(spDetached, sp);
          sp = (PersistentObjectItf) pm.speedoAttachCopy(spDetached, map);
        }
        //put the element of the collection attribute in the elements attribute (the opposite of the jdoDetachCopy method)
        speedoAddOnAttach(sp, false);
      } else {
        //just add the java object in the collection
        speedoAddOnAttach(elem, false);
      }
    }
  }
 
  public void refresh(POManagerItf pm, Map map, Collection fgHints){
    commonRefreshRetrieve(pm, map, fgHints, true);
  }
 
  public void retrieve(POManagerItf pm, Map map, Collection fgHints){
    commonRefreshRetrieve(pm, map, fgHints, false);
  }
 
  /**
   *
   * @param pm
   * @param map
   * @param fgHints
   * @param refresh: if true, call refresh, else call retrieve
   */
  //TODO: what about refreshing Collection of String, Integer, Date???? 
  private void commonRefreshRetrieve(POManagerItf pm, Map map, Collection fgHints, boolean refresh){
    //get an interator on the PIndexed elements
    Iterator it = elements.iterator();
    while(it.hasNext()){
      //get the PIndexElement
      CollectionElem iElem = (CollectionElem) it.next();
      //get the po associated
      PersistentObjectItf sp = (PersistentObjectItf) iElem.getElement(pm);
      if(map != null && !map.containsKey(sp.getPName())){
        synchronized(fgHints){
          if (refresh) { //refresh
                        pm.speedoRefresh(sp, map, fgHints);
          } else { //retrieve
                        pm.speedoRetrieve(sp, map, fgHints);
          }
         
        }
      }
    }
  }
 
    // ------------------------------------------------------------------------
    // IMPLEMENTATION OF THE Collection INTERFACE
    // ------------------------------------------------------------------------

    public boolean add(Object o) {
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "add()");
    }
    GenClassElement gce = speedoAdd(o, false);

        //Send the event about the new element adding
    if (gce != null) {
      Object obj = o;
      if (obj instanceof PName) {
        obj = gce.getElement(((PersistentObjectItf) gcpo).speedoGetPOManager());
      }
            if (obj instanceof PersistentObjectItf) {
        gcpo.fireSpeedoElementAdded(obj);
      }
        }
        return gce != null;
    }

    public boolean addAll(Collection c) {
        Iterator it = c.iterator();
        boolean changed = false;
        while (it.hasNext()) {
            changed |= add(it.next());
        }
        return changed;
    }

    public void clear() {
        if (elements.size() > 0) {
      if (Debug.ON && getLogger() != null) {
        logger.log(BasicLevel.DEBUG, "clear()");
      }
            Collection c = new ArrayList(this);
            Iterator i = c.iterator();
            while (i.hasNext()) {
                remove(i.next());
            }
            elements.clear(); // efficient, but does not work with relations
            supportDelta = false;
        } else {
      if (Debug.ON && getLogger() != null) {
        logger.log(BasicLevel.DEBUG, "clear(): empty collection");
      }
    }
    }

    public boolean contains(Object o) {
        tmpelem.setElement(o);
        Iterator it = elements.iterator();
        while (it.hasNext()) {
            PIndexedElem e = (PIndexedElem) it.next();
            if (e.equals(tmpelem) && e.getElemStatus() != PIndexedElem.ELEM_DELETED) {
        if (Debug.ON && getLogger() != null) {
          logger.log(BasicLevel.DEBUG, "contains(): yes");
        }
                return true;
            }
        }
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "contains(): no");
    }
        return false;
    }

    public boolean containsAll(Collection c) {
        Iterator it = c.iterator();
        while (it.hasNext()) {
            if (!contains(it.next())) {
                return false;
            }
        }
        return true;
    }

    public boolean equals(Object o) {
        return (o instanceof Collection) &&
                ((Collection) o).size() == size() &&
                containsAll((Collection) o);
    }

    public boolean isEmpty() {
        if (elements.isEmpty()) {
            return true;
        }
        Iterator it = elements.iterator();
        // The set is empty if it contains only deleted indexed elements
        while (it.hasNext()) {
            if (((PIndexedElem) it.next()).getElemStatus() != PIndexedElem.ELEM_DELETED) {
                return false;
            }
        }
        return true;
    }

    public Iterator iterator() {
        return new PIndexedElemIterator(elements, this,
                ((PersistentObjectItf) gcpo).speedoGetPOManager(), ((Loggable) gcpo).getLogger());
    }

    public boolean remove(Object o) {
        GenClassElement gce = speedoRemove2(o);
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "remove: gce=" + gce);
    }
        if (gce != null) {
      Object obj = gce.getElement(((PersistentObjectItf) gcpo).speedoGetPOManager());
            if (obj != null) {
              gcpo.fireSpeedoElementRemoved(obj);
      }
        }
        return gce != null;
    }

    public boolean removeAll(Collection c) {
        Iterator it = c.iterator();
        boolean removed = true;
        while (it.hasNext()) {
            removed &= remove(it.next());
        }
        return removed;
    }

    public boolean retainAll(Collection c) {
        throw new UnsupportedOperationException();
    }

    public int size() {
        Iterator it = elements.iterator();
        int size = 0;
        while (it.hasNext()) {
            if (((PIndexedElem) it.next()).getElemStatus() != PIndexedElem.ELEM_DELETED) {
                size++;
            }
        }
        return size;
    }

    public Object[] toArray() {
        ArrayList al = new ArrayList(elements.size());
        Iterator it = elements.iterator();
        while (it.hasNext()) {
            GenClassElement gce = (GenClassElement) it.next();
            if (gce.getElemStatus() != PIndexedElem.ELEM_DELETED) {
                al.add(gce.getElement());
            }
        }
        return al.toArray();
    }

    public Object[] toArray(Object[] a) {
        ArrayList al = new ArrayList(elements.size());
        Iterator it = elements.iterator();
        while (it.hasNext()) {
            GenClassElement gce = (GenClassElement) it.next();
            if (gce.getElemStatus() != PIndexedElem.ELEM_DELETED) {
                al.add(gce.getElement());
            }
        }
        return al.toArray(a);
    }

    // ------------------------------------------------------------------------
    // IMPLEMENTATION OF THE PGenClassAccessor INTERFACE
    // ------------------------------------------------------------------------

    public PIndexedElem createPIndexedElem(GenClassAccessor gca) {
        return new CollectionElem(gca);
    }

    // ------------------------------------------------------------------------
    // IMPLEMENTATION OF THE SpeedoGenClassCoherence INTERFACE
    // ------------------------------------------------------------------------

    public boolean speedoAdd(Object o, Object hints) {
        return speedoAdd(o, false) != null;
    }

    protected GenClassElement speedoAdd(Object o, boolean allowDuplicates) {
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "speedoAdd(, " + allowDuplicates + ")");
    }
    if (o instanceof PersistentObjectItf && !((PersistentObjectItf) o).speedoIsActive()) {
      //if not detached, then make it persistent
      if (((PersistentObjectItf) o).speedoGetReferenceState().getDetachedStatus()
          == DetachedLifeCycle.DETACHED_NONE) {
        ((AbstractGenClassHome) getSpeedoPO().speedoGetHome())
          .makePersistent(null, (PersistentObjectItf) o,
              (SpeedoGenClassPO) getSpeedoPO(), null);
      } else {
        //attach it
        //problem the map is re-instanciated on each add...
        o = getSpeedoPO().speedoGetPOManager().speedoAttachCopy(o, new HashMap());
      }
    }
    synchronized (this) {
      if (!allowDuplicates && contains(o)) {
        if (Debug.ON && getLogger() != null) {
          logger.log(BasicLevel.DEBUG, "speedoAdd(, " + allowDuplicates + "): already exist");
        }
        return null;
      }
      if (Debug.ON && getLogger() != null) {
        logger.log(BasicLevel.DEBUG, "speedoAdd(, " + allowDuplicates + "): adding");
      }
      // Put it in the "elements" list
      GenClassElement element = (GenClassElement) createPIndexedElem();
      element.setElement(o);
            return (elements.add(element) ? element : null);
        }
    }

    protected GenClassElement speedoAddOnAttach(Object o, boolean allowDuplicates) {
      //TODO: implement the method
      return speedoAdd(o, allowDuplicates);
    }
   
    public boolean speedoRemove(Object o, Object hints) {
    if (Debug.ON && getLogger() != null) {
      logger.log(BasicLevel.DEBUG, "speedoRemove()");
    }
    return speedoRemove2(o) != null;
    }

  public void forceDetachedDirty() {
  }

  public void restoreDetachedNone() {
  }

}
TOP

Related Classes of org.objectweb.speedo.genclass.collection.CollectionAccessor

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.