GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

GATJobDescription.c

Go to the documentation of this file.
00001 /** @file GATJobDescription.c
00002  *  Source file for the GATJobDescription class.
00003  *
00004  *  An instance of this class describes a job to be run.
00005  *
00006  *  @date Thu Oct 23 2003
00007  *
00008  *  @version $Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATJobDescription.c,v 1.14 2004/04/02 12:31:57 hartmutkaiser Exp $
00009  *
00010  *  Copyright (C) Hartmut Kaiser
00011  *  This file is part of the GAT Engine.
00012  *  Contributed by Hartmut Kaiser <hartmutkaiser [at] t-online [dot] de>.
00013  *
00014  *  Use, modification and distribution is subject to the Gridlab Software
00015  *  License. (See accompanying file GLlicense.txt or copy at
00016  *  http://www.gridlab.org/GLlicense.txt)
00017  */
00018  
00019 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATJobDescription.c,v 1.14 2004/04/02 12:31:57 hartmutkaiser Exp $";
00020  
00021 /* System Header Files */
00022 #include <stdlib.h>
00023 #include <string.h>
00024 
00025 /* GAT Header Files */
00026 #include "GATInternal.h"
00027 #include "GATErrors.h"
00028 #include "GATType.h"
00029 #include "GATRegistry.h"
00030 #include "GATResourceDescription.h"
00031 #include "GATSoftwareDescription.h"
00032 #include "GATJobDescription.h"
00033 #include "GATResourceBroker.h"
00034 #include "GATXdsWrapper.h"
00035 
00036 /* define the vtable types */
00037 GATOBJECT_DEFINE_VTABLE(GATJobDescription);
00038 GATSERIALISABLE_DEFINE_VTABLE(GATJobDescription);
00039 
00040 /* define the converters to/from GATObject */
00041 GATOBJECT_DEFINE_CONVERTERS(GATJobDescription)
00042 
00043 /* Macros */
00044 
00045 /* Structures, unions and enums */
00046 struct GATJobDescription_S {
00047   GATJobDescription_vtable *GATObject__vtable;
00048   GATJobDescription_ISerialisable_vtable *GATSerialisable__vtable;
00049 
00050   GATBool isdirty;
00051   GATSoftwareDescription software;
00052   GATResourceDescription description;
00053   GATResource resource;
00054 };
00055 
00056 /* Static function prototypes */
00057 static int
00058 GATJobDescription_DeSerialise_Create(GATContext context, GATObject stream, 
00059   GATSoftwareDescription software, GATType type, GATObject resource, 
00060   GATJobDescription *new_object);
00061 
00062 /* File scope variables */
00063 GATJobDescription_vtable GATJobDescription__vtable = {
00064   GATJobDescription_GetType,
00065   GATJobDescription_Destroy,
00066   GATJobDescription_Equals,
00067   GATJobDescription_Clone,
00068   GATJobDescription_GetInterface,
00069   NULL
00070 };
00071 
00072 static GATJobDescription_ISerialisable_vtable 
00073   GATJobDescription_ISerialisable__vtable = 
00074 {
00075   GATJobDescription_Serialise,
00076   GATJobDescription_DeSerialise,
00077   GATJobDescription_GetIsDirty,
00078 };
00079 
00080 /* External functions */
00081 
00082 /** GATJobDescription_Register_GATSerialisable
00083  *  The GATJobDescription_Register_GATSerialisable function registers the serialization
00084  *  vtable with the GAT engine to allow generic object creation.
00085  *  This function is called by the GAT engine, there is no need to use it 
00086  *  directly.
00087  */
00088 GATResult GATJobDescription_Register_GATSerialisable(void)
00089 {
00090   return GATObject_Register_GATSerialisable(GATType_GATJobDescription, 
00091     &GATJobDescription_ISerialisable__vtable);
00092 }
00093 
00094 /** GATJobDescription_Create
00095  *  @brief Create a new GATJobDescription object
00096  *
00097  *  The function @c GATJobDescription_Create creates a new 
00098  *  GATJobDescription object
00099  *
00100  *  @param context The GAT context to use while thie initialisation of the 
00101  *        new object.
00102  *  @param software The software description of the job to describe.
00103  *  @param resource The resource description for the job to describe.
00104  *
00105  *  @return Returns a handle to the newly created GATJobDescription object.
00106  *        Returns 0 (zero) if an error occurs.
00107  */
00108 GATJobDescription 
00109 GATJobDescription_Create_Description(GATContext context, 
00110   GATSoftwareDescription_const software, 
00111   GATResourceDescription_const description)
00112 {
00113   GATResult err_code = GAT_MEMORYFAILURE;
00114   GATJobDescription retval = (GATJobDescription) malloc(
00115     sizeof(struct GATJobDescription_S));
00116 
00117   GAT_UNUSED_PARAMETER(context);
00118   if (NULL != retval)
00119   {
00120     memset(retval, 0, sizeof(struct GATJobDescription_S));
00121     retval->GATObject__vtable = &GATJobDescription__vtable;
00122     retval->GATSerialisable__vtable = &GATJobDescription_ISerialisable__vtable;
00123     retval->isdirty = GATFalse;
00124     
00125     err_code = GATSoftwareDescription_Clone(software, 
00126       &retval->software);
00127 
00128     if (GAT_SUCCEEDED(err_code))
00129     {
00130       GATObject_const object = GATResourceDescription_ToGATObject_const(description);
00131       GATType type = GATObject_GetType(object);
00132 
00133       if (GATType_GATSoftwareResourceDescription == type)
00134       {
00135         err_code = GATSoftwareResourceDescription_Clone(
00136           (GATSoftwareResourceDescription_const) description, 
00137           (GATSoftwareResourceDescription *) &retval->description);
00138       }
00139       else
00140       {
00141         err_code = GATHardwareResourceDescription_Clone(
00142           (GATHardwareResourceDescription_const) description, 
00143           (GATHardwareResourceDescription *) &retval->description);
00144       }
00145     }
00146   }
00147   
00148   /* error handling */
00149   if (GAT_FAILED(err_code))
00150   {
00151     GATJobDescription_Destroy(&retval);
00152   }
00153 
00154   return retval;
00155 }
00156 
00157 /** GATJobDescription_Create
00158  *  @brief Create a new GATJobDescription object
00159  *
00160  *  The function @c GATJobDescription_Create creates a new 
00161  *  GATJobDescription object
00162  *
00163  *  @param context The GAT context to use while thie initialisation of the 
00164  *        new object.
00165  *  @param software The software description of the job to describe.
00166  *  @param resource The resource for the job to describe.
00167  *
00168  *  @return Returns a handle to the newly created GATJobDescription object.
00169  *        Returns 0 (zero) if an error occurs.
00170  */
00171 GATJobDescription 
00172 GATJobDescription_Create(GATContext context, 
00173   GATSoftwareDescription_const software, GATResource_const resource)
00174 {
00175   GATResult err_code = GAT_MEMORYFAILURE;
00176   GATJobDescription retval = (GATJobDescription) malloc(
00177     sizeof(struct GATJobDescription_S));
00178 
00179   GAT_UNUSED_PARAMETER(context);
00180   if (NULL != retval)
00181   {
00182     memset(retval, 0, sizeof(struct GATJobDescription_S));
00183     retval->GATObject__vtable = &GATJobDescription__vtable;
00184     retval->GATSerialisable__vtable = &GATJobDescription_ISerialisable__vtable;
00185     retval->isdirty = GATFalse;
00186     
00187     err_code = GATSoftwareDescription_Clone(software, 
00188       &retval->software);
00189     if (GAT_SUCCEEDED(err_code)) 
00190     {
00191       err_code = GATResource_Clone(resource, &retval->resource);
00192     }
00193   }
00194   
00195   /* error handling */
00196   if (GAT_FAILED(err_code))
00197   {
00198     GATJobDescription_Destroy(&retval);
00199   }
00200   
00201   return retval;
00202 }
00203 
00204 /** void GATJobDescription_Destroy(GATJobDescription *resource)
00205  *
00206  *  The function GATJobDescription_Destroy is the destructor used to
00207  *  free all the memory allocated by an GATJobDescription instance.
00208  *
00209  *  @param description The pointer to the GATJobDescription to destroy
00210  */
00211 void
00212 GATJobDescription_Destroy(GATJobDescription *object)
00213 {
00214   if (NULL != object && NULL != *object)
00215   {
00216     GATSoftwareDescription_Destroy(&(*object)->software);
00217     if (NULL != (*object)->description)
00218     {
00219       GATObject obj = GATResourceDescription_ToGATObject(
00220         (*object)->description);
00221       GATObject_Destroy(&obj);
00222     }
00223     if (NULL != (*object)->resource)
00224     {
00225       GATResource_Destroy(&(*object)->resource);
00226     }
00227     free(*object);
00228     *object = NULL;
00229   }
00230 }
00231 
00232 /** GATJobDescription_Equals
00233  *  @brief Compare two GATJobDescription objects
00234  *
00235  *  The function @c GATJobDescription_Equals compares two objects of the
00236  *  @c GATJobDescription type.
00237  *
00238  *  @param lhs The first list to compare
00239  *  @param rhs The second list to compare
00240  *  @param isequal The pointer to the location, where the outcome of the 
00241  *        function has to be stored.
00242  *
00243  *  @return An error code.
00244  */
00245 GATResult
00246 GATJobDescription_Equals(GATJobDescription_const lhs,
00247   GATJobDescription_const rhs, GATBool *isequal)
00248 {
00249   GATResult retval = GAT_INVALID_HANDLE;
00250 
00251   if (NULL != lhs && NULL != rhs)
00252   {
00253     retval = GAT_INVALID_PARAMETER;
00254     if (NULL != isequal)
00255     {
00256       retval = GATSoftwareDescription_Equals(lhs->software, 
00257         rhs->software, isequal);
00258       if (GAT_SUCCEEDED(retval) && GATTrue == *isequal)
00259       {
00260         if (NULL != lhs->description && NULL != rhs->description)
00261         {
00262           retval = GATResourceDescription_Equals(lhs->description, 
00263             rhs->description, isequal);
00264         }
00265         else if (NULL != lhs->resource && NULL != rhs->description)
00266         {
00267           retval = GATResource_Equals(lhs->resource, rhs->resource, 
00268             isequal);
00269         }
00270         else 
00271         {
00272           *isequal = GATFalse;
00273           retval = GAT_SUCCESS;
00274         }
00275       }
00276     }
00277   }
00278   return retval;
00279 }
00280 
00281 /** GATJobDescription_Clone
00282  *  @brief Clone the given GATJobDescription
00283  *
00284  *  The function @c GATJobDescription_Clone generates a (deep) copy of 
00285  *  the given GATJobDescription. 
00286  *
00287  *  @param description The object to clone
00288  *  @param new_object The pointer, through which the result is to be 
00289  *        returned.
00290  *
00291  *  @return An error type.
00292  */
00293 GATResult
00294 GATJobDescription_Clone(GATJobDescription_const object, 
00295   GATJobDescription *new_handle)
00296 {
00297   GATResult retval = GAT_INVALID_HANDLE;
00298   if (NULL != object)
00299   {
00300     if (NULL == new_handle)
00301     {
00302       retval = GAT_INVALID_PARAMETER;
00303     }
00304     else
00305     {
00306       GATJobDescription new_object = 
00307         (GATJobDescription) malloc(sizeof(struct GATJobDescription_S));
00308       
00309       *new_handle = NULL;
00310       if (NULL == new_object)
00311       {
00312         retval = GAT_MEMORYFAILURE;
00313       }
00314       else
00315       {
00316         memset(new_object, 0, sizeof(struct GATJobDescription_S));
00317         new_object->GATObject__vtable = &GATJobDescription__vtable;
00318         new_object->GATSerialisable__vtable = &GATJobDescription_ISerialisable__vtable;
00319         new_object->isdirty = object->isdirty;
00320         
00321         retval = GATSoftwareDescription_Clone(object->software, 
00322           &new_object->software);
00323         if (GAT_SUCCEEDED(retval))
00324         {
00325           if (NULL != object->description)
00326           {
00327             GATType type = GATResourceDescription_GetType(object->description);
00328             retval = GATResourceDescription_Clone(type, 
00329               object->description, &new_object->description);
00330           }
00331           if (NULL != object->resource)
00332           {
00333             retval = GATResource_Clone(object->resource,
00334               &new_object->resource);
00335           }
00336         }
00337       }
00338     
00339       if (GAT_FAILED(retval))
00340       {
00341         GATJobDescription_Destroy(&new_object);
00342       }
00343       else
00344       {
00345         *new_handle = new_object;
00346       }
00347     }
00348   }
00349   return retval;
00350 }
00351 
00352 /** GATType GATJobDescription_GetType(GATJobDescription_const resource)
00353  *  @brief Return the type of the GATJobDescription
00354  *
00355  *  The function @c GATJobDescription_GetType always returns 
00356  *  @c #GATType_GATJobDescription. 
00357  *
00358  *  @param object The object to inspect
00359  *
00360  *  @return Returns always @c #GATType_GATJobDescription. 
00361  */
00362 GATType
00363 GATJobDescription_GetType(GATJobDescription_const description)
00364 {
00365   GAT_UNUSED_PARAMETER(description);
00366   return GATType_GATJobDescription;
00367 }
00368 
00369 /** GATResult GATJobDescription_GetInterface(GATJobDescription_const file, GATInterface iftype, void const **ifp)
00370  *  @brief Get an interface supported by a GATObject
00371  *
00372  *  The function GATJobDescription_GetInterface allows to get a pointer to an 
00373  *  additional interface supported by this GATJobDescription.
00374  *
00375  *  @param object The object to be asked for the new interface.
00376  *  @param iftype The interface the object is to be asked for.
00377  *  @param ifp The pointer, through which the result is to be returned.
00378  *
00379  *  @return An error type.
00380  */
00381 GATResult 
00382 GATJobDescription_GetInterface(GATJobDescription_const object, GATInterface iftype, 
00383   void const **ifp)
00384 {
00385   GATResult retval = GAT_INVALID_PARAMETER;
00386 
00387   if (NULL != ifp)
00388   {
00389     *ifp = NULL;
00390     if (GATInterface_ISerialisable == iftype)
00391     {
00392       *ifp = (void const *) &object->GATSerialisable__vtable;
00393       retval = GAT_SUCCESS;
00394     }
00395     else
00396     {
00397       retval = GAT_NO_INTERFACE;
00398     }
00399   }
00400   return retval;
00401 }
00402 
00403 
00404 /* Return the software description describing this job */
00405 GATSoftwareDescription_const
00406   GATJobDescription_GetSoftwareDescription(GATJobDescription_const object)
00407 {
00408   GATSoftwareDescription_const retval = NULL;
00409   if (NULL != object)
00410   {
00411     retval = object->software;
00412   }
00413   return retval;
00414 }
00415 
00416 /* Return the of the resources the job can be run on */
00417 GATResourceDescription_const
00418   GATJobDescription_GetResourceDescription(GATJobDescription_const object)
00419 {
00420   GATResourceDescription_const retval = NULL;
00421   if (NULL != object)
00422   {
00423     retval = object->description;
00424   }
00425   return retval;
00426 }
00427   
00428 /* Return the resource the job SHOULD be run on */
00429 GATResource_const
00430   GATJobDescription_GetResource(GATJobDescription_const object)
00431 {
00432   GATResource_const retval = NULL;
00433   if (NULL != object)
00434   {
00435     retval = object->resource;
00436   }
00437   return retval;
00438 }
00439 
00440 
00441 /* GATSerialisable API */
00442 
00443 /** GATResult GATJobDescription_Serialise(GATJobDescription object, GATObject stream, GATBool clear_dirty)
00444  *  @brief Serialise a GATJobDescription object
00445  *
00446  *  The function GATJobDescription_Serialise serialises the given GATFIle object 
00447  *  into the given stream. 
00448  *
00449  *  @param object The GATJobDescription object to serialise.
00450  *  @param stream The stream interface to use for the serialisation.
00451  *  @param clear_dirty If the clear_dirty parameter is set to GATTrue, the 
00452  *        internal dirty flag of this object is to be reset (no used here)
00453  *
00454  *  @return An error code.
00455  */
00456 GATResult 
00457 GATJobDescription_Serialise(GATJobDescription object, GATObject stream, 
00458   GATBool clear_dirty)
00459 {
00460   GATResult retval = GAT_INVALID_HANDLE;
00461   if (NULL != object)
00462   {
00463     if (NULL != object->description)
00464     {
00465       retval = GATXds_SerialiseObject(
00466         GATJobDescription_ToGATObject(object), stream, clear_dirty, 0, 
00467         "uint32 uint32 object object", 
00468         GATJOBDESCRIPTION_VERSION1, GATType_GATResourceDescription,
00469         object->software, clear_dirty, object->description, clear_dirty);
00470     }
00471     else if (NULL != object->resource)
00472     {
00473       retval = GATXds_SerialiseObject(
00474         GATJobDescription_ToGATObject(object), stream, clear_dirty, 0, 
00475         "uint32 uint32 object object", 
00476         GATJOBDESCRIPTION_VERSION1, GATType_GATResource,
00477         object->software, clear_dirty, object->resource, clear_dirty);
00478     }
00479     else 
00480     {
00481      retval = GAT_INVALID_PARAMETER;
00482     }
00483 
00484     if (GAT_SUCCEEDED(retval) && clear_dirty)
00485     {
00486       object->isdirty = GATFalse;
00487     }
00488   }
00489   return retval;
00490 }
00491 
00492 /** GATJobDescription_VersionCallback
00493  *
00494  *  The function GATJobDescription_VersionCallback is used as a callback function
00495  *  during the de-serialisation of a GATJobDescription. It should be provided to test,
00496  *  whether the de-serialised version matches the expected version.
00497  *
00498  *  @param version The version number, which was de-serialised from the stream.
00499  *
00500  *  @return This function should return GATTrue, if the version matches the 
00501  *        expected value (version is valid), GATFalse otherwise.
00502  *
00503  *  @remark This function is called from the GAT engine, there is no need to 
00504  *        call it directly.
00505  */
00506 static GATBool
00507 GATJobDescription_VersionCallback(GATuint32 version)
00508 {
00509   GATBool retval = GATFalse;
00510   if ((version & ~GATJOBDESCRIPTION_MINOR_MASK) <= GATJOBDESCRIPTION_LASTVERSION)
00511   {
00512     retval = GATTrue;
00513   }
00514   return retval;
00515 }
00516 
00517 /** GATJobDescription_DeSerialiseCallback
00518  *
00519  *  The function GATJobDescription_DeSerialiseCallback is used as a callback function
00520  *  during the de-serialisation of a GATJobDescription. It should be provided for the
00521  *  instantiation of the new GATJobDescription object based on the already de-serialised 
00522  *  data items and the de-serialisation of the associated CPI provider data for 
00523  *  the given object.
00524  *
00525  *  @param context The GAT context to be used for object construction.
00526  *  @param stream The stream interface to use for the serialisation.
00527  *  @param object The pointer to the variable, which should receive the newly 
00528  *        constructed object.
00529  *  @param version The version of the saved data read from the input stream.
00530  *  @param args This parameter is the pointer to the va_list containing 
00531  *        pointers to the already de-serialised data items accordingly to the
00532  *        format string, provided during the call to the 
00533  *        GATJobDescription_DeSerialise function.
00534  *
00535  *  @return An error code.
00536  *
00537  *  @remark This function is called from the GAT engine, there is no need to 
00538  *        call it directly.
00539  */
00540 static GATResult 
00541 GATJobDescription_DeSerialiseCallback(GATContext context, GATObject stream, 
00542   GATObject *new_object, GATuint32 version, va_list args)
00543 {
00544   GAT_USES_STATUS(context, "GATJobDescription_DeSerialiseCallback");
00545   
00546   /* the version was eaten already */
00547   GATuint32 *type = va_arg(args, GATuint32 *);
00548   GATSoftwareDescription *software = va_arg(args, GATSoftwareDescription *);
00549   GATObject *resource = va_arg(args, GATObject *);
00550 
00551   GATJobDescription object = NULL;
00552   
00553   GAT_UNUSED_PARAMETER(version);
00554   
00555   /* construct the new object */
00556   GAT_CREATE_STATUS(GATJobDescription_DeSerialise_Create(context, stream, 
00557     *software, (GATType)*type, *resource, &object));
00558     
00559   if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00560   {
00561     if (NULL != object)
00562     {
00563       *new_object = GATJobDescription_ToGATObject(object);
00564     }
00565     else
00566     {
00567       GATJobDescription_Destroy(&object);
00568       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00569     }
00570   }
00571   
00572   return GAT_RETURN_STATUS();
00573 }
00574 
00575 /** GATJobDescription GATJobDescription_DeSerialise(GATContext context, GATObject stream, GATBool clear_dirty)
00576  *  @brief De-serialise a GATJobDescription object
00577  *
00578  *  The function GATJobDescription_DeSerialise de-serialises a streamed  
00579  *  GATJobDescription object from the given stream  It constructs a new 
00580  *  instance of the de-serialised object.
00581  *
00582  *  @param context The GAT context to be used for object construction.
00583  *  @param stream The stream interface to use for the serialisation.
00584  *  @param result The pointer to a variable, which receives the status code of
00585  *        the operation.
00586  *
00587  *  @return The newly constructed GATJobDescription object.
00588  */
00589 GATJobDescription 
00590 GATJobDescription_DeSerialise(GATContext context, GATObject stream, 
00591   GATResult *result)
00592 {
00593   GAT_USES_STATUS(context, "GATJobDescription_DeSerialise");
00594   GATObject object = NULL;     /* the new object will be created here */
00595   
00596   /* we must provide all instance data items to be de-serialised for this
00597      GATJobDescription object accordingly to the provided format string */
00598   GATuint32 version = 0;
00599   
00600   GATSoftwareDescription software = NULL;
00601   GATuint32 type = GATType_NoType;
00602   GATObject resource = NULL;
00603   
00604   /* read the data */
00605   GATResult retval = GATXds_DeSerialiseObject(context, stream, 
00606     GATJobDescription_DeSerialiseCallback, GATJobDescription_VersionCallback, 
00607     &object, "uint32 uint32 object object", &version, &type, &software, &resource);
00608   GAT_CREATE_STATUS(retval);
00609   GATSoftwareDescription_Destroy(&software);
00610   GATObject_Destroy(&resource);
00611 
00612   if (NULL != result)
00613   { 
00614     *result = GAT_RETURN_STATUS();
00615   }
00616   else
00617   {
00618     GAT_STORE_STATUS();
00619   }
00620   return GATObject_ToGATJobDescription(object);
00621 }
00622 
00623 /** GATJobDescription_GetIsDirty
00624  *  
00625  *  The function GATJobDescription_GetIsDirty retrieves the status of the dirty flag of 
00626  *  this GATJobDescription object.
00627  *
00628  *  @param file The GATJobDescription object to inspect for its dirty status.
00629  *  @param isdirty The pointer to a variable, which receives the dirty status.
00630  *
00631  *  @return An error code.
00632  */
00633 GATResult 
00634 GATJobDescription_GetIsDirty(GATJobDescription_const object, GATBool *isdirty)
00635 {
00636   GATResult retval = GAT_INVALID_HANDLE;
00637   if (NULL != object)
00638   {
00639     if (NULL != isdirty)
00640     {
00641       *isdirty = object->isdirty;
00642       retval = GAT_SUCCESS;
00643     }
00644     else
00645     {
00646       retval = GAT_INVALID_PARAMETER;
00647     }
00648   }  
00649   return retval;
00650 }
00651 
00652 
00653 /* internal functions */
00654 
00655 /*  GATJobDescription_internal_GetEnvironment
00656  *  
00657  *  The function GATJobDescription_internal_GetEnvironment gets a reference to
00658  *  the table, which stores the environment variables for the job described.
00659  *
00660  *  @param jd The job description to query for the environemnt table.
00661  *  @param env The variable receiving the resulting Table reference.
00662  *
00663  *  @return An error code.
00664  */   
00665 GATResult
00666 GATJobDescription_internal_GetEnvironment(GATJobDescription jd, GATTable *env)
00667 {
00668   GATResult retval = GAT_INVALID_HANDLE;
00669   if (NULL != jd)
00670   {
00671     GATObject obj = NULL;
00672     retval = GATTable_internal_Get_GATObjectRef(
00673       GATSoftwareDescription_GetAttributes(jd->software), "environment", &obj);
00674     
00675     if (GAT_FAILED(retval))
00676     {
00677       /* need to create the environment table in the softwrae description */
00678       GATTable environment = GATTable_Create();
00679 
00680       if (NULL != environment)
00681       {
00682         GATTable attr = NULL;
00683         retval = GATSoftwareDescription_internal_GetAttributesRef(jd->software, 
00684           &attr);
00685         
00686         if (GAT_SUCCEEDED(retval))
00687         {
00688           retval = GATTable_Add_GATObject(attr, "environment", 
00689             GATTable_ToGATObject_const(environment));
00690         }
00691 
00692         /* access the newly created table */
00693         retval = GATTable_internal_Get_GATObjectRef(attr, "environment", &obj);
00694         
00695         GATTable_Destroy(&environment);
00696       }
00697       else
00698       {
00699         retval = GAT_MEMORYFAILURE;
00700       }
00701     }
00702     
00703     if (GAT_SUCCEEDED(retval))
00704     {
00705       if (NULL != env)
00706       {
00707         *env = GATObject_ToGATTable(obj);
00708         retval = GAT_SUCCESS;
00709       }
00710       else
00711       {
00712         retval = GAT_INVALID_PARAMETER;
00713       }
00714     }
00715   }
00716   return retval;
00717 }
00718 
00719 /* Local functions */
00720 
00721 /** GATJobDescription_DeSerialise_Create
00722  *
00723  *  The function GATJobDescription_DeSerialise_Create creates a new 
00724  *  GATJobDescription object.
00725  *
00726  *  @param context The GAT context to use for creation of the GATJobDescription 
00727  *        object.
00728  *  @param stream The object from which the adaptor should read the streamed
00729  *        instance data.
00730  *  @param software The software description to use for creation of the new job 
00731  *        description.
00732  *  @param type This parameter should be equal to GATType_GATResourceDescription
00733  *        or GATType_GATResource. 
00734  *  @param resource This is the resoure description or the resource to be used 
00735  *        for creation of the new job description.
00736  *  @param new_object The pointer to the variable, which should receive the 
00737  *        newly constructed GATJobDescription object.
00738  *
00739  *  @return An error code.
00740  */
00741 static GATResult 
00742 GATJobDescription_DeSerialise_Create(GATContext context, GATObject stream, 
00743   GATSoftwareDescription software, GATType type, GATObject resource, 
00744   GATJobDescription *object)
00745 {
00746   GAT_USES_STATUS(context, "GATJobDescription_DeSerialise_Create");
00747   GATJobDescription new_object = 
00748     (GATJobDescription) malloc(sizeof(struct GATJobDescription_S));
00749 
00750   GAT_UNUSED_PARAMETER(stream);
00751   if(NULL != new_object)
00752   {
00753     memset(new_object, 0, sizeof(struct GATJobDescription_S));
00754     new_object->GATObject__vtable = &GATJobDescription__vtable;
00755     new_object->GATSerialisable__vtable = &GATJobDescription_ISerialisable__vtable;
00756     new_object->isdirty = GATFalse;
00757 
00758     GAT_CREATE_STATUS(GATSoftwareDescription_Clone(software, 
00759       &new_object->software));
00760     if (GATType_GATResourceDescription == type)
00761     {
00762       GATType resource_type = GATObject_GetType(resource);
00763       GAT_CREATE_STATUS(GATResourceDescription_Clone(resource_type,
00764         (GATResourceDescription) resource, &new_object->description));
00765     }
00766     else if (GATType_GATResource == type)
00767     {
00768       GAT_CREATE_STATUS(GATResource_Clone((GATResource) object, 
00769         &new_object->resource));
00770     }
00771     else
00772     {
00773       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00774     }
00775   }
00776   
00777   if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00778   {
00779     if (NULL != new_object)
00780     {
00781       *object = new_object;
00782     }
00783     else
00784     {
00785       GATJobDescription_Destroy(&new_object);
00786       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00787     }
00788   }
00789   else
00790   {
00791     GATJobDescription_Destroy(&new_object);
00792   }
00793   
00794   return GAT_RETURN_STATUS();
00795 }
00796