--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef anna_dbos_AutoObject_hpp
+#define anna_dbos_AutoObject_hpp
+
+#include <anna/dbos/Object.hpp>
+
+namespace anna {
+
+namespace dbos {
+
+
+/**
+ Facilita el uso de los punteros a objectos obtenidos a partir de los datos guardados en un medio fisico.
+
+ La idea de esta clase es que el constructor y el destructor de esta clase cooperan para reservar y/o
+ liberar correctamente la instancia de T asociada a esta instancia.
+
+ \param T Clase que vamos a gestionar.
+
+ En el siguiente ejemplo podemos ver la forma habitual de trabajar con un objeto persistente tiene
+ el incoveniente de que tenemos que tener en cuenta cada una de las situaciones en las que la
+ referencia obtenida mediante el metodo \em instantiate debe ser liberada.
+
+ \code
+ void Application::getServerSocketsData (vector <SocketData>& serverSocketsData) const
+ throw (RuntimeException)
+ {
+ LOGMETHOD (TraceMethod ("anna::Application", "getServerSocketsData", ANNA_FILE_LOCATION));
+
+ Facility* facility (NULL);
+ FacilityLoader facilityLoader;
+
+ try {
+ facility = Facility::instantiate (facilityLoader.setKey (a_thisFacility)); // (1)
+ LOGDEBUG (Logger::write (Logger::Debug, facility->asString (), ANNA_FILE_LOCATION));
+
+ getSocketsData (getThisHostName (), facility->getName (), a_thisCell, a_thisInstance, serverSocketsData);
+
+ Facility::release (facility);
+ }
+ catch (dbos::DatabaseException& edbos) {
+ Facility::release (facility);
+ throw RuntimeException (edbos.getText (), ANNA_FILE_LOCATION);
+ }
+ catch (RuntimeException&) { // Tenemos que capturar esta excepcion para liberar el recurso.
+ Facility::release (facility);
+ throw;
+ }
+ }
+ \endcode
+
+ Como podemos ver a continuacion el siguiente metodo es mucho mas sencillo y aporta la gran ventaja de que
+ el sistema trabaja por nosotros para liberar correctamente los recursos.
+
+ \code
+ void Application::getServerSocketsData (vector <SocketData>& serverSocketsData) const
+ throw (RuntimeException)
+ {
+ LOGMETHOD (TraceMethod ("anna::Application", "getServerSocketsData", ANNA_FILE_LOCATION));
+
+ AutoObject <Facility> facility;
+ FacilityLoader facilityLoader;
+
+ try {
+ facility = Facility::instantiate (facilityLoader.setKey (a_thisFacility)); // (1)
+
+ LOGDEBUG (Logger::write (Logger::Debug, facility->asString (), ANNA_FILE_LOCATION));
+
+ getSocketsData (getThisHostName (), facility->getName (), a_thisCell, a_thisInstance, serverSocketsData);
+ }
+ catch (dbos::DatabaseException& edbos) {
+ throw RuntimeException (edbos.getText (), ANNA_FILE_LOCATION);
+ }
+ }
+ \endcode
+*/
+template <typename T> class AutoObject {
+public:
+ /**
+ Constructor.
+ \param t Instancia del objeto asociado a esta instancia.
+ \warning La instancia deberia haber sido obtenida mediate la invocacion a \em T::instantiate de la
+ clase persistente.
+ */
+ explicit AutoObject(T* t) : a_t(t) {;}
+
+ /**
+ Constructor.
+ */
+ AutoObject() : a_t(NULL) {;}
+
+ /**
+ Destructor. Invoca al metodo \em T::release
+ */
+ ~AutoObject() { if(a_t != NULL) T::release(a_t); }
+
+ /**
+ Operador ->
+ Permite invocar a metodos de la clase T.
+ \return La instancia de la clase T asociada a esta instancia.
+ */
+ T* operator -> () const throw() { return a_t; }
+
+ /**
+ Operador copia.
+ \param t Referencia al objeto que vamos a tratar.
+ \return La instancia de la clase T asociada a esta instancia.
+ */
+ T* operator = (T* t) throw() {
+ if(a_t != t) {
+ T::release(a_t);
+ a_t = t;
+ }
+
+ return a_t;
+ }
+
+ /**
+ Operador copia.
+ \param other Referencia al objeto que vamos a tratar.
+ \return La instancia de la clase T asociada a esta instancia.
+ */
+ T* operator = (const AutoObject <T>& other) throw(RuntimeException) {
+ return (this != &other) ? (*this = T::duplicate(other.a_t)) : a_t;
+ }
+
+ /**
+ Operador de conversion.
+ \return La instancia de la clase T asociada a esta instancia.
+ */
+ operator T*() const throw() { return a_t; }
+
+private:
+ T* a_t;
+};
+
+
+}
+}
+
+
+
+#endif
+
+