/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openjpa.persistence;

import java.util.Iterator;
import java.util.List;

import org.apache.openjpa.kernel.DelegatingExtent;

/**
 * An extent is a logical view of all instances of a class.
 *
 * @author Abe White
 * @since 0.4.1
 */
public class ExtentImpl<T>
    implements Extent<T> {

    private final EntityManagerImpl _em;
    private final DelegatingExtent _extent;
    private FetchPlan _fetch = null;

    /**
     * Constructor; supply delegate.
     */
    public ExtentImpl(EntityManagerImpl em, org.apache.openjpa.kernel.Extent<T> extent) {
        _em = em;
        _extent = new DelegatingExtent(extent,
            PersistenceExceptions.getRollbackTranslator(em));
    }

    /**
     * Delegate.
     */
    @Override
    public org.apache.openjpa.kernel.Extent<T> getDelegate() {
        return _extent.getDelegate();
    }

    @Override
    public Class<T> getElementClass() {
        return _extent.getElementType();
    }

    @Override
    public boolean hasSubclasses() {
        return _extent.hasSubclasses();
    }

    @Override
    public OpenJPAEntityManager getEntityManager() {
        return _em;
    }

    @Override
    public FetchPlan getFetchPlan() {
        _em.assertNotCloseInvoked();
        _extent.lock();
        try {
            if (_fetch == null)
                _fetch = ((EntityManagerFactoryImpl) _em.
                    getEntityManagerFactory()).toFetchPlan(_extent.getBroker(),
                    _extent.getFetchConfiguration());
            return _fetch;
        } finally {
            _extent.unlock();
        }
    }

    @Override
    public boolean getIgnoreChanges() {
        return _extent.getIgnoreChanges();
    }

    @Override
    public void setIgnoreChanges(boolean ignoreChanges) {
        _em.assertNotCloseInvoked();
        _extent.setIgnoreChanges(ignoreChanges);
    }

    @Override
    public List<T> list() {
        _em.assertNotCloseInvoked();
        return _extent.list();
    }

    @Override
    public Iterator<T> iterator() {
        _em.assertNotCloseInvoked();
        return _extent.iterator();
    }

    @Override
    public void closeAll() {
        _extent.closeAll();
    }

    @Override
    public int hashCode() {
        return ((_extent == null) ? 0  : _extent.hashCode());
    }

    @Override
    public boolean equals(Object other) {
        if (other == this)
            return true;
        if ((other == null) || (other.getClass() != this.getClass()))
            return false;
        if (_extent == null)
        	return false;

        return _extent.equals(((ExtentImpl) other)._extent);
	}
}
