package ${package};

##
## Copyright 2001-2005 The Apache Software Foundation.
##
## Licensed 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.
##

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

import javax.jdo.Extent;
import javax.jdo.FetchPlan;
import javax.jdo.Query;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.JDOUserException;
import javax.jdo.Transaction;

// Model class imports
#foreach ( $class in $classes )
#if ( $class.getMetadata( $storeClassMetadataId ).storable && ${class.packageName} != ${package} )
import ${class.packageName}.${class.name};
#end
#end

/**
 * Generated JPox storage mechanism for ${model.name}.
 *
 * @author Mr Modello
 */
public class ${model.name}JPoxStore
{
#foreach ( $class in $classes )
#if ( $class.getMetadata( $storeClassMetadataId ).storable )
        public final static String ${class.name}_DETAIL_FETCH_GROUP = "${class.name}_detail";
#end
#end
    private static ThreadLocal threadState = new ThreadLocal();

    private PersistenceManagerFactory pmf;

    public ${model.name}JPoxStore( PersistenceManagerFactory pmf )
    {
        this.pmf = pmf;
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    public static class ThreadState
    {
        private PersistenceManager pm;

        private Transaction tx;

        private int depth;

        public PersistenceManager getPersistenceManager()
        {
            return pm;
        }

        public Transaction getTransaction()
        {
            return tx;
        }

        public int getDepth()
        {
            return depth;
        }
    }

    // ----------------------------------------------------------------------
    // Transaction Management Methods
    // ----------------------------------------------------------------------

    public ThreadState getThreadState()
    {
        return (ThreadState) threadState.get();
    }

    public PersistenceManager begin()
    {
        ThreadState state = (ThreadState) threadState.get();

        if ( state == null )
        {
            state = new ThreadState();

            state.pm = pmf.getPersistenceManager();

            state.tx = state.pm.currentTransaction();

            state.tx.begin();

            threadState.set( state );

            return state.pm;
        }
        else
        {
            state.depth++;

            return state.pm;
        }
    }

    public void commit()
    {
        ThreadState state = (ThreadState) threadState.get();

        if ( state == null )
        {
            throw new IllegalStateException( "commit() must only be called after begin()." );
        }

        if ( state.depth > 0 )
        {
            state.depth--;

            return;
        }

        threadState.set( null );

        try
        {
            state.tx.commit();
        }
        finally
        {
            if ( state.tx.isActive() )
            {
                state.tx.rollback();
            }

            closePersistenceManager( state.pm );
        }
    }

    public void rollback()
    {
        ThreadState state = (ThreadState) threadState.get();

        if ( state == null )
        {
            // The tx is not active because it has already been committed or rolled back

            return;
        }

        threadState.set( null );

        try
        {
            if ( state.tx.isActive() )
            {
                state.tx.rollback();
            }
        }
        finally
        {
            closePersistenceManager( state.pm );
        }
    }

#foreach ( $class in $classes )
#if ( $class.getMetadata( $storeClassMetadataId ).storable )
    // ----------------------------------------------------------------------
    // ${class.name} CRUD
    // ----------------------------------------------------------------------

    public Object add${class.name}( $class.name o )
    {
        try
        {
            PersistenceManager pm = begin();

            pm.makePersistent( o );

            Object id = pm.getObjectId( o );

            commit();

            return id;
        }
        finally
        {
            rollback();
        }
    }

#if ( $class.getIdentifierFields( $version ).size() > 0 )
    public Object store${class.name}( $class.name o )
    {
        try
        {
            PersistenceManager pm = begin();

            pm.makePersistent( o );

            Object id = pm.getObjectId( o );

            commit();

            return id;
        }
        finally
        {
            rollback();
        }
    }
#end

    public void delete${class.name}( String id )
    {
        try
        {
            PersistenceManager pm = begin();

            Query query = pm.newQuery( ${class.name}.class );

            query.setIgnoreCache( true );

            // TODO: Use all known identifier fields in this filter
            query.setFilter( "this.id == \"" + id + "\"" );

            Collection result = (Collection) query.execute();

            if ( result.isEmpty() )
            {
                throw new RuntimeException( "No such object of type \"${class.name}\" with id: \"" + id + "\"." );
            }

            pm.deletePersistentAll( result );

            commit();
        }
        finally
        {
            rollback();
        }
    }

#if ( $class.getIdentifierFields( $version ).size() == 1 )
    public ${class.name} get${class.name}( String id, boolean detach )
        throws Exception
    {
        try
        {
            PersistenceManager pm = begin();

            pm.getFetchPlan().setGroup( FetchPlan.DEFAULT );

            pm.getFetchPlan().addGroup( "${class.name}_detail" );

            Query query = pm.newQuery( ${class.name}.class );

            query.setIgnoreCache( true );

            #foreach ( $idField in $class.getIdentifierFields( $version ) )
            query.setFilter( "this.${idField.name} == \"" + id + "\"" );
            #end

            Collection result = (Collection) query.execute();

            if ( result.isEmpty() )
            {
                throw new RuntimeException( "No such object of type \"${class.name}\" with id: \"" + id + "\"." );
            }

            ${class.name} object = (${class.name}) result.iterator().next();

            if ( detach )
            {
                object = (${class.name}) pm.detachCopy( object );
            }

            commit();

            return object;
        }
        finally
        {
            rollback();
        }
    }
#end

    public ${class.name} get${class.name}ByJdoId( Object id, boolean detach )
    {
        try
        {
            PersistenceManager pm = begin();

            pm.getFetchPlan().setGroup( FetchPlan.DEFAULT );

            pm.getFetchPlan().addGroup( "${class.name}_detail" );

            ${class.name} object = (${class.name}) pm.getObjectById( id, true );

            if ( detach )
            {
                object = (${class.name}) pm.detachCopy( object );
            }

            commit();

            return object;
        }
        finally
        {
            rollback();
        }
    }

    public Collection get${class.name}Collection( boolean detach, String filter, String ordering )
    {
        try
        {
            PersistenceManager pm = begin();

            Extent extent = pm.getExtent( ${class.name}.class, true );

            Query query = pm.newQuery( extent );

            if ( ordering != null )
            {
                query.setOrdering( ordering );
            }

            if ( filter != null )
            {
                query.setFilter( filter );
            }

            Collection result = ((Collection) query.execute() );

            Collection collection;

            // TODO: Why did was this done with a iterator and not makeTransientAll()? -- trygve
            //       I would guess I had to do it this way to make sure JPOX fetched all fields
            //       so this should probably go away now if detach works like expected.
            //       Also; why refresh()?
            if ( detach )
            {
                collection = new ArrayList();

                for ( Iterator it = result.iterator(); it.hasNext(); )
                {
                    Object object = it.next();

                    pm.refresh( object );

                    object = pm.detachCopy( object );

                    collection.add( object );
                }
            }
            else
            {
                collection = result;
            }

            commit();

            return collection;
        }
        finally
        {
            rollback();
        }
    }
#end

#end

    public ${model.name}ModelloMetadata get${model.name}ModelloMetadata( boolean detach )
    {
        try
        {
            PersistenceManager pm = begin();

            pm.getFetchPlan().setGroup( FetchPlan.DEFAULT );

            Query query = pm.newQuery( ${model.name}ModelloMetadata.class );

            query.setIgnoreCache( true );

            Collection result = (Collection) query.execute();

            if ( result.isEmpty() )
            {
                return null;
            }

            ${model.name}ModelloMetadata object = (${model.name}ModelloMetadata) result.iterator().next();

            if ( detach )
            {
                object = (${model.name}ModelloMetadata) pm.detachCopy( object );
            }

            commit();

            return object;
        }
        finally
        {
            rollback();
        }
    }

    public void store${model.name}ModelloMetadata( ${model.name}ModelloMetadata o )
    {
        try
        {
            PersistenceManager pm = begin();

            pm.makePersistent( o );

            commit();
        }
        finally
        {
            rollback();
        }
    }

    public void eraseModelFromDatabase()
    {
        try
        {
            PersistenceManager pm = begin();

            Query query = pm.newQuery( ${model.name}ModelloMetadata.class );

            query.setIgnoreCache( true );

            query.deletePersistentAll();

            #foreach ($class in $classes)
            query = pm.newQuery( ${class.name}.class );

            query.setIgnoreCache( true );

            query.deletePersistentAll();
            #end


            commit();
        }
        finally
        {
            rollback();
        }
    }

    // ----------------------------------------------------------------------
    // Utility Methods
    // ----------------------------------------------------------------------

    private void closePersistenceManager( PersistenceManager pm )
    {
        try
        {
            pm.close();
        }
        catch( JDOUserException ex )
        {
            ex.printStackTrace();
        }
    }
}
