Package org.objectweb.speedo.query.jdo

Source Code of org.objectweb.speedo.query.jdo.POIterator

/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* 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
*
*
*
* Contact: speedo@objectweb.org
*
* Authors: S.Chassande-Barrioz.
*
*/

package org.objectweb.speedo.query.jdo;

import org.objectweb.jorm.api.PClassMapping;
import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.api.PMapper;
import org.objectweb.jorm.naming.api.PName;
import org.objectweb.speedo.mapper.api.JormFactory;
import org.objectweb.speedo.mim.api.HomeItf;
import org.objectweb.speedo.pm.api.POManagerItf;
import org.objectweb.speedo.pm.jdo.api.JDOPOManagerItf;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

import javax.jdo.Extent;
import javax.jdo.FetchPlan;
import javax.jdo.JDOException;
import javax.jdo.JDOUserException;
import javax.jdo.PersistenceManager;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

/**
*/
public class JDOExtent implements Extent {

    private Class candidateClass = null;
    private boolean hasSubclasses = false;
    private boolean prefetch = false;
    private JDOPOManagerItf pm = null;
    private PClassMapping pcm;
    private Logger logger;
    private List iterators;
    private int nextUnused;

  /**
   * The fetch plan.
   * When an Extent is retrieved from a PersistenceManager, its FetchPlan is initialized to the same settings
   * as that of the PersistenceManager.
   * Subsequent modifications of the Extent's FetchPlan are not reflected
   * in the FetchPlan of the PersistenceManager.
   */
  private FetchPlan fetchPlan;
    /**
     * create a new SpeedoExtent object, this object is not obtained by a
     * call to 'new' by the client application, but by the PersistenceManager
     * object with getExtent() method
     * @param candidateClass
     * @param hasSubclasses
     * @param pm
     */
    public JDOExtent(Class candidateClass,
                        boolean hasSubclasses,
                        JDOPOManagerItf pm,
                        JormFactory jf,
                        boolean prefetch,
                        Logger logger) {
        iterators = new ArrayList();
        nextUnused = 0;
        this.candidateClass = candidateClass;
        this.hasSubclasses = hasSubclasses;
      this.prefetch = prefetch;
        this.logger = logger;
        this.pm = pm;
        //initialize the fetch plan to the same settings as that of the peristence manager
        this.fetchPlan = pm.getFetchPlan();
        try {
            pcm = jf.getPClassMapping(candidateClass);
        } catch (PException e) {
            throw new JDOUserException("The class '" + candidateClass
                    + "' is not mapped or is not a persistent class",
                    new Exception[]{e});
        }
        if (pcm == null) {
            throw new JDOUserException("The class '" + candidateClass
                    + "' is not mapped or is not a persistent class");
        }
        if (prefetch) {
            prefetch = ((HomeItf) pcm).getPrefetchOnExtent();
        }
    }

    /**
     * Returns an iterator over all the instances in the Extent.
     * @return an iterator over all instances in the Extent
     */
    public synchronized Iterator iterator() {
        POIterator poi;
        int size = iterators.size();
        if (nextUnused < size) {
            // free POIterator instances availlable
            poi = (POIterator) iterators.get(nextUnused);
        } else {
            // Allocate a POIterator
            poi = new POIterator();
            iterators.add(nextUnused, poi);
        }
        nextUnused++;
        try {
            poi.open(pm, pcm, hasSubclasses, prefetch);
        } catch (PException e) {
            throw new JDOException("Problem to fetch an Iterator over the class "
                    + candidateClass.getName(), new Exception[]{e});
        }
        return poi;
    }

    /**
     * Returns whether this Extent was defined to contain subclasses.
     * @return true if this Extent was defined to contain instances
     * that are of a subclass type
     */
    public boolean hasSubclasses() {
        return hasSubclasses;
    }

    /**
     * An Extent contains all instances of a particular Class in the data
     * store; this method returns the Class of the instances
     * @return the Class of instances of this Extent
     */
    public Class getCandidateClass() {
        return candidateClass;
    }

    /**
     * An Extent is managed by a PersistenceManager; this method gives access
     * to the owning PersistenceManager.
     * @return the owning PersistenceManager
     */
    public PersistenceManager getPersistenceManager() {
        return pm;
    }

  public FetchPlan getFetchPlan(){
    return fetchPlan;
  }
 
  public void setFetchPlan(FetchPlan fp){
    fetchPlan = fp;
  }
   
    /**
     * Close all Iterators associated with this Extent instance.  Iterators closed
     * by this method will return false to hasNext() and will throw
     * NoSuchElementException on next().  The Extent instance can still be used
     * as a parameter of Query.setExtent, and to get an Iterator.
     */
    public synchronized void closeAll() {
        if (iterators.size() == 0) {
            return;
        }
        for(int i=0; i<nextUnused; i++) {
            POIterator poi = (POIterator) iterators.get(i);
            try {
                poi.close();
            } catch (PException e) {
                logger.log(BasicLevel.ERROR,
                        "Impossible to close an Iterator over the class "
                        + candidateClass.getName(), e);
            }
        }
        nextUnused = 0;
    }

    /**
     * Close an Iterator associated with this Extent instance.  Iterators closed
     * by this method will return false to hasNext() and will throw
     * NoSuchElementException on next().  The Extent instance can still be used
     * as a parameter of Query.setExtent, and to get an Iterator.
     * @param it an iterator obtained by the method iterator() on this Extent instance.
     */
    public synchronized void close(Iterator it) {
        if (it instanceof POIterator) {
            try {
                ((POIterator) it).close();
            } catch (PException e) {
                logger.log(BasicLevel.ERROR,
                        "Impossible to close an Iterator over the class "
                        + candidateClass.getName(), e);
            }
            int idx = iterators.indexOf(it);
            if (idx == -1) {
                logger.log(BasicLevel.WARN,
                        "The Iterator not managed by this Extent has been closed");
            } else if (idx < nextUnused) {
                iterators.add(iterators.remove(idx));
                nextUnused--;
            } else {
                //nothing to do the iterator is already unused
            }
        }
    }
}
class POIterator implements Iterator {

    private JDOPOManagerItf pm;
    private Iterator pnameIt;
    private boolean closed;
    private boolean connectionOpened;
    private PMapper mapper;
    private Object connection;

    public void open(JDOPOManagerItf pm,
                     PClassMapping pcm,
                     boolean subclass,
                     boolean prefetch) throws PException {
        this.pm = pm;
        closed = false;
        this.mapper = pcm.getPMapper();
        Object cs = pm.getConnectionSpec();
        if (cs == null) {
            connection = mapper.getConnection();
        } else {
            connection = mapper.getConnection(cs);
        }
        connectionOpened = true;
        pnameIt = pcm.getPNameIterator(connection, subclass, prefetch, pm.currentTransaction());
    }

    public void close() throws PException {
        closed = true;
        if (connectionOpened) {
            connectionOpened = false;
            mapper.closeConnection(connection);
        }
        pm = null;
        mapper = null;
        connection = null;
        pnameIt = null;
    }

    public boolean hasNext() {
        if (closed || pm.isPOMClosed()) {
            throw new NoSuchElementException();
        }
        if (connectionOpened && !pnameIt.hasNext()) {
            connectionOpened = false;
            try {
                mapper.closeConnection(connection);
            } catch (PException e) {
            }
        }
        return pnameIt.hasNext();
    }

    public Object next() {
        if (closed || pm.isPOMClosed() || !pnameIt.hasNext()) {
            if (connectionOpened) {
                connectionOpened = false;
                try {
                    mapper.closeConnection(connection);
                } catch (PException e) {
                }
            }
            throw new NoSuchElementException();
        }
        PName pn = (PName) pnameIt.next();
        return pm.getObjectById(pn, false);
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }

 
    protected void finalize() throws Throwable {
        super.finalize();
        if (connectionOpened && mapper!=null) {
            connectionOpened = false;
            try {
                mapper.closeConnection(connection);
            } catch (PException e) {
            }
        }
    }
}
TOP

Related Classes of org.objectweb.speedo.query.jdo.POIterator

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.