>>I'm developing a patch against the ADB C code generator to allow it to
handle polymorphism correctly...

>>Say you have a complexType A, which is abstract. Then there are
complexTypes A1 and A2, which extend A and are not abstract.

>>The second case, however, is quite problematic. The only way to know
which type is being returned is, of course, during runtime, by looking
at the xsi:type property. This is relatively easy to do with Axiom, but
the problem is how to invoke the right create method, but the problem is
that for this to work correctly, it's necessary to invoke the "create"
and "deserialize" methods for the right subtype (the ones for A won't
do, as they aren't aware of the specific properties of A1 and A2). I
thought of creating one global hash table with the create/deserialize
methods for all types when generating the stub for the service, but it
doesn't strike me as a particularly elegant solution. Does anyone have
any other suggestions?

>>It's at times like these I wish C had classes and I could just let the
language handle the issue itself ;-)

>>Cheers,
>>Sérgio



Hi Sérgio,

As Dimuthu suggested in an earlier post, you can change the structure of
each subtype to start with a char array, then casting the object to a
char * will give you the contents of this char array.

E.g.  The source file for type A1 will contain

struct adb_A1
{
...
}

If we change this to:
struct adb_A1
{
axis2_char_t property_Type[64];
...
}

And in the adb_A1_create, add
strcpy(_A1->property_Type, "adb_A1");


In the same way, adb_A2.c contains

struct adb_A2
{
axis2_char_t property_Type[64];
...
}

in adb_A2_create
strcpy(_A2->property_Type, "adb_A2");


So now consider an ADB object C that contains an element of base type A.
in adb_C.c you will have 


adb_C_set_A(C_t *C, env, A_t *A)
{
...
}

Change this to 
adb_C_set_A(C_t *C, env, void *A)

The void * will be correctly stored in the property or array list.

During serialization, you can use the following:

if (strcmp((char *)element, "adb_A1") == 0) {

      if(!adb_A1_is_particle())
      {
          axutil_stream_write(stream, env, start_input_str,
start_input_str_len);
      }
      
      adb_A1_serialize((adb_A1_t*)element, 
                                                           env,
current_node, parent_element,
 
adb_A1_is_particle() || AXIS2_FALSE, namespaces, next_ns_index);
      
      if(!adb_A1_is_particle())
      {
          axutil_stream_write(stream, env, end_input_str,
end_input_str_len);
      }
}

And repeat for A2, etc.

Now the final usage pattern looks like this:

Adb_C = adb_C_create(env);
Adb_A1 = adb_A1_create(env);
Adb_C_set_A(Adb_C, env, Adb_A1);

And the C will correctly serialize the element as an A1.


I hope this helps your work.  I am really interested in seeing this
implemented in WSDL2C.

Carl
  _____  

"Ce message est confidentiel, à l'usage exclusif du destinataire
ci-dessus et son contenu ne représente en aucun cas un engagement de la
part de AXA, sauf en cas de stipulation expresse et par écrit de la part
de AXA. Toute publication, utilisation ou diffusion, même partielle,
doit être autorisée préalablement. Si vous n'êtes pas destinataire de ce
message, merci d'en avertir immédiatement l'expéditeur."

"This e-mail message is confidential, for the exclusive use of the
addressee and its contents shall not constitute a commitment by AXA,
except as otherwise specifically provided in writing by AXA. Any
unauthorized disclosure, use or dissemination, either whole or partial,
is prohibited. If you are not the intended recipient of the message,
please notify the sender immediately."

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to