/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program 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 distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.hibernate.action.internal;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Map;

import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostCollectionRemoveEvent;
import org.hibernate.event.spi.PostCollectionRemoveEventListener;
import org.hibernate.event.spi.PreCollectionRemoveEvent;
import org.hibernate.event.spi.PreCollectionRemoveEventListener;
import org.hibernate.persister.collection.CollectionPersister;

import com.huawei.soa.ldae.partition.PartitionInfo;
import com.huawei.soa.ldae.partition.PartitionIntegrationFactory;

/**
 * The action for removing a collection
 */
public final class CollectionRemoveAction extends CollectionAction
{
    private final Object affectedOwner;

    private boolean emptySnapshot;

    /**
     * Removes a persistent collection from its loaded owner.
     *
     * Use this constructor when the collection is non-null.
     *
     * @param collection
     *            The collection to to remove; must be non-null
     * @param persister
     *            The collection's persister
     * @param id
     *            The collection key
     * @param emptySnapshot
     *            Indicates if the snapshot is empty
     * @param session
     *            The session
     *
     * @throws AssertionFailure
     *             if collection is null.
     */
    public CollectionRemoveAction(final PersistentCollection collection, final CollectionPersister persister,
            final Serializable id, final boolean emptySnapshot, final SessionImplementor session)
    {
        super(persister, collection, id, session);
        if (collection == null)
        {
            throw new AssertionFailure("collection == null");
        }
        this.emptySnapshot = emptySnapshot;
        // the loaded owner will be set to null after the collection is removed,
        // so capture its value as the affected owner so it is accessible to
        // both pre- and post- events
        this.affectedOwner = session.getPersistenceContext().getLoadedCollectionOwnerOrNull(collection);
    }

    /**
     * Removes a persistent collection from a specified owner.
     *
     * Use this constructor when the collection to be removed has not been loaded.
     *
     * @param affectedOwner
     *            The collection's owner; must be non-null
     * @param persister
     *            The collection's persister
     * @param id
     *            The collection key
     * @param emptySnapshot
     *            Indicates if the snapshot is empty
     * @param session
     *            The session
     *
     * @throws AssertionFailure
     *             if affectedOwner is null.
     */
    public CollectionRemoveAction(final Object affectedOwner, final CollectionPersister persister,
            final Serializable id, final boolean emptySnapshot, final SessionImplementor session)
    {
        super(persister, null, id, session);
        if (affectedOwner == null)
        {
            throw new AssertionFailure("affectedOwner == null");
        }
        this.emptySnapshot = emptySnapshot;
        this.affectedOwner = affectedOwner;
    }

    @Override
    public void execute() throws HibernateException
    {
        preRemove();

        if (!emptySnapshot)
        {
            // an existing collection that was either non-empty or uninitialized
            // is replaced by null or a different collection
            // (if the collection is uninitialized, hibernate has no way of
            // knowing if the collection is actually empty without querying the db)
            PartitionInfo partitionInfo = PartitionIntegrationFactory.getInstance().getPartitionInfo(
                    getPersister().getOwnerEntityPersister().getEntityName());

            try
            {
				if (partitionInfo != null && partitionInfo.isPartition() && getCollection().getOwner() != null)
                {
                    PartitionIntegrationFactory.getInstance().setCurrentPartitionValue(
							(BigDecimal) ((Map) getCollection().getOwner()).get(partitionInfo.getFieldName()));
                }
                getPersister().remove(getKey(), getSession());
            }
            finally
            {
                PartitionIntegrationFactory.getInstance().removeCurrentPartitionValue();
            }
        }

        final PersistentCollection collection = getCollection();
        if (collection != null)
        {
            getSession().getPersistenceContext().getCollectionEntry(collection).afterAction(collection);
        }

        evict();
        postRemove();

        if (getSession().getFactory().getStatistics().isStatisticsEnabled())
        {
            getSession().getFactory().getStatisticsImplementor().removeCollection(getPersister().getRole());
        }
    }

    private void preRemove()
    {
        final EventListenerGroup<PreCollectionRemoveEventListener> listenerGroup = listenerGroup(EventType.PRE_COLLECTION_REMOVE);
        if (listenerGroup.isEmpty())
        {
            return;
        }
        final PreCollectionRemoveEvent event = new PreCollectionRemoveEvent(getPersister(), getCollection(),
                eventSource(), affectedOwner);
        for (PreCollectionRemoveEventListener listener : listenerGroup.listeners())
        {
            listener.onPreRemoveCollection(event);
        }
    }

    private void postRemove()
    {
        final EventListenerGroup<PostCollectionRemoveEventListener> listenerGroup = listenerGroup(EventType.POST_COLLECTION_REMOVE);
        if (listenerGroup.isEmpty())
        {
            return;
        }
        final PostCollectionRemoveEvent event = new PostCollectionRemoveEvent(getPersister(), getCollection(),
                eventSource(), affectedOwner);
        for (PostCollectionRemoveEventListener listener : listenerGroup.listeners())
        {
            listener.onPostRemoveCollection(event);
        }
    }
}

@@ -5239,61 +5239,355 @@
     
-PartitionIntegrationFactory.getInstance().setCurrentP
+BigDecimal partitionValue = null;%0A                    if(getCollection() != null)%0A                    %7B%0A                    %09partitionValue = (BigDecimal) ((Map) getCollection().getOwner()).get(partitionInfo.getFieldName());%0A                    %7D%0A                    else if(this.affectedOwner != null)%0A                    %7B%0A                    %09p
 arti
@@ -5599,17 +5599,11 @@
 alue
-(%0A%09%09%09%09%09%09%09
+ = 
 (Big
@@ -5622,34 +5622,26 @@
 ap) 
-getCollection().get
+this.affected
 Owner
-()
 ).ge
@@ -5671,16 +5671,126 @@
 dName())
+;%0A                    %7D%0A%09%09%09%09%09PartitionIntegrationFactory.getInstance().setCurrentPartitionValue(partitionValue
 );%0A     

fix nullPointException