Search code examples
delphiwsdl

wsdl importer seems to generate faulty code - inhertinace / abstract types issue


i think the wsdl importer from delphi xe3 seems to generate wrong code for a certain wsdl / xsd. The webservice itself is not made by us, but we need to consume it. I stripped out the relevant parts from the xsd schema we got supplied to illustrate the problem.

here's part of the XSD that i think causes problems

    <xs:element name="request">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="Demand"  name="demand"  minOccurs="1" maxOccurs="1" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="Demand" abstract="true">
        <xs:sequence>           
            <xs:element name="person" type="Person" minOccurs="1" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Person" abstract="true">
        <xs:sequence>            
            <xs:element name="name" minOccurs="0" maxOccurs="1">                
        </xs:sequence>
        <xs:attribute name="key" type="xs:ID" use="required" />        
    </xs:complexType>

    <xs:complexType name="MoralPerson">
        <xs:complexContent>
            <xs:extension base="Person">
                <xs:sequence>
                    <xs:element name="juridicalForm">
                        <xs:simpleType>
                            <xs:restriction base="xs:int">
                                <xs:maxInclusive value="10" />
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:element>               
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="GarnishmentDemand">
       <xs:complexContent>
           <xs:extension base="Demand">
               <xs:sequence>
                   <xs:element name="saleTotalAmount" type="Amount" minOccurs="1" maxOccurs="1" /> 
                   <xs:element name="saleDate" type="xs:date" minOccurs="1" maxOccurs="1" /> 
               </xs:sequence>
           </xs:extension>
       </xs:complexContent>
    </xs:complexType>

here's some of the code delphi generated

  Person = class(TRemotable)
  private
    Fkey: string;
    Fname_: name_;
    Fname__Specified: boolean;
    procedure Setname_(Index: Integer; const Aname_: name_);
    function  name__Specified(Index: Integer): boolean;
  published
    property key:                    string   Index (IS_ATTR) read Fkey write Fkey;
    property name_:                  name_    Index (IS_OPTN) read Fname_ write Setname_ stored name__Specified;
  end; 

 MoralPerson = class(Person)
  private
    FjuridicalForm: juridicalForm;
  published
    property juridicalForm: juridicalForm  read FjuridicalForm write FjuridicalForm;
  end;

  Demand     = array of Person;

  CreateNoticeOneRequest = class(TRemotable)
  private
    Fdossier: Dossier;
    Fdemand: Demand;
  public
    destructor Destroy; override;
  published
    property demand:  Demand   read Fdemand write Fdemand;
  end;

  GarnishmentDemand = class(TRemotable)
  private
    FsaleTotalAmount: Amount;
    FsaleDate: TXSDate;
  public
    destructor Destroy; override;
  published
    property saleTotalAmount: Amount   read FsaleTotalAmount write FsaleTotalAmount;
    property saleDate:        TXSDate  read FsaleDate write FsaleDate;
  end;

when i look at the XSD the demand type seems to be the base class for all other demand types and only contains an array of persons, so all derived classes from demand (like GarnishmentDemand) should have an array of persons. The problem is that delphi declared the Demand type itself as an array of person and i think it should have been a class, so when i create a GarnishmentDemand i'm unable to access the person array.

Is this a bug in the wsdl importer, am i seeing it all wrong or are the wsdl/xsd supplied faulty ? if it is a bug can it somehow be corrected? I tried changing numerous options in de wsdl importer tool before pressing finish but the Demand type was always declared as an array of person instead of a class.

If it isn't a bug then i don't see how i should be able to access the persons array when using the GarnishmentDemand type?


Solution

  • i found a workaround solution for this problem.

    i added a dummy element in the xsd for the Demand type like this:

    <xs:complexType name="Demand" abstract="true">
        <xs:sequence>           
            <xs:element name="person" type="Person" minOccurs="1" maxOccurs="unbounded" />
            <xs:element name="dummy" type="xs:boolean" minOccurs="0" maxOccurs="1" nillable="true"/>
        </xs:sequence>
    </xs:complexType>
    

    then i imported the wsdl/xsd again in delphi XE3 and removed the dummy element from the generated code. Delphi now defines the Demand type as a class and all other demands (like the GarnishmentDemand) inherit from the Demand class and i'm able to access the person array like it was intended in the first place

      Demand = class(TRemotable)
      private
        Fperson: Array_Of_Person;
        Fdummy: Boolean;
        Fdummy_Specified: boolean;
        procedure Setdummy(Index: Integer; const ABoolean: Boolean);
        function  dummy_Specified(Index: Integer): boolean;
      public
        destructor Destroy; override;
      published
        property person: Array_Of_Person  Index (IS_UNBD) read Fperson write Fperson;
        property dummy:  Boolean          Index (IS_OPTN or IS_NLBL) read Fdummy write Setdummy stored dummy_Specified;
      end;
    
      GarnishmentDemand = class(Demand)
      private
        FsaleTotalAmount: Amount;
        FsaleDate: TXSDate;
      public
        destructor Destroy; override;
      published
        property saleTotalAmount: Amount   read FsaleTotalAmount write FsaleTotalAmount;
        property saleDate:        TXSDate  read FsaleDate write FsaleDate;
      end;
    

    I'll test to see if delphi XE4 contains the same bug, if it does, i'll see if i can file a report with embarcaderro QA