// ==================================================
// Copyright 2013.
// Siemens Product Lifecycle Management Software Inc.
// All Rights Reserved.
// ==================================================

#ifndef FCLASSES_ACQUIRELOCK_HXX
#define FCLASSES_ACQUIRELOCK_HXX

/**
   @file

   Manages locks on objects.
*/

#include <unidefs.h>

#include <fclasses/libfclasses_exports.h>
namespace Teamcenter
{
    /**
       @brief Manages a lock on an object.
       
       It obtains a write lock on an object.
       <br/>This is required if the caller wish to save a modified version of the object or delete it.
       
       It is a convenient C++ class wrapper to AOM_refresh.

       Use this class where you would use AOM_refresh( tag, TRUE ).
       <br/>It will ensure that the object will be unlocked when you go out of scope.
       So you do not have to remember to do an unlock on the object.
       
       Use as follows:
       @code
       try
       {
        AcquireLock lock( mytag );
        // This will throw IFail Exception on failure to lock.
        // Make sure caller has this nested in a high level try/catch block.

        // Do the process and forget about unlocking the object, as it will automatically be done.
        }
        catch(const IFail&)
        {
        }
        @endcode
    */
class FCLASSES_API AcquireLock
{
public:
    /**
       Constructor that does not lock any object.
       <br/>The lock() method needs to be invoked to complete the lock on a given object.
    */
    AcquireLock();
        
    /**
       Constructs the instance and locks the object.
    */
    AcquireLock( 
        tag_t object       /**< (I) The object to lock. */
        );
        
    /**
       Locks the object.
    */
    void lock(
        tag_t object       /**< (I) The object to lock. */
        );
        
    /**
       Unlocks any locked object.
    */
    void unlock();
        
    /**
       Skips the refresh of the objects, which means that the changes to the in-memory representation
       of the object will remain when the AcquireLock instance goes out of the C++ scope.
    */
    void forget();
        
    /**
       Destructor.
       <br/>Unlocks any locked object.
    */
    virtual ~AcquireLock();
        
    /**
       Returns the locking state of the underlying POM object.
    */
    bool isLocked() const;
        
    /**
       Determines if the underlying POM object has been locked by this instance.
    */
    bool isLockedByMe() const;
        
        
private:
    /**
       Copy constructor.
    */
    AcquireLock( const AcquireLock&  other );
        
    /**
       Assignment operator.
    */
    AcquireLock&  operator=( const AcquireLock&  other );
        
    /** The locked object */
    tag_t m_lockedObj;
        
    /** The status of the object lock prior to being locked by this instance. */
    bool m_bLockedPrior;
};
}
#include <fclasses/libfclasses_undef.h>
#endif
