      *> ooctrl(+p) required for COM and Java classes
      *> ooctrl(-f) used to preserve case of method names for Java
      $set ooctrl(+p) ooctrl(-f)

      ****************************************************************
      * Copyright (C) 1996 - 2000 Micro Focus International Ltd.     *
      * All Rights Reserved.                                         *
      ****************************************************************
      * The program demonstrates the use of Java invoking Object     *
      * COBOL and vice versa using Java objects as parameters.       *
      *                                                              *
      * The class below implements two methods which sort a Java     *
      * vector object given another object which is able to compare  *
      * elements within the vector.                                  *
      * The methods are invoked from the Java class "SortDemo".      *
      *                                                              *
      * Compile and link using: cbllink -D -Rm SortDemo.cbl          *
      *                                                              *
      * REQUIREMENTS: Sun JDK 1.2.2 (or later) must be installed.    *
      *                                                              *
      * $(#) V1.0                                                    *
      ****************************************************************

       class-id. SortDemo inherits from javabase.
       class-control.
	 SortDemo is class "SortDemo"
         javabase is class "javabase"
         javasup is class "javasup"
      *> Java vector class (always include package)
         vectorClass is class "$JAVA$java/util/Vector"
         .

       class-object.
       end class-object.

       object.

       method-id. "sortVector".
       local-storage section.
       01 vectorSize pic x(4) comp-5.
       01 halfSize pic x(4) comp-5.
       01 restSize pic x(4) comp-5.
       01 i pic x(4) comp-5.
       01 vectorv1 object reference.
       01 vectorv2 object reference.
       01 atObj object reference.
       01 theContext object reference.
       01 theHome object reference.
       01 theself object reference.
       01 sortResulta object reference.
       01 sortResultb object reference.
       linkage section.
       01 result object reference.
       01 vector object reference.
       01 compare object reference.
       procedure division using by value vector 
                          by value compare 
                          returning result.
      *> If vector is NULL, return a NULL object
         if (vector = null)
             set result to null
             exit method
         end-if

      *> If vector has < 2 members, it must already be sorted
         invoke vector "size" returning vectorSize
         if (vectorSize < 2)
             set result to vector
             exit method
         end-if

      * Split the vector into two vectors of roughly equal size
         divide vectorSize by 2 giving halfSize
         subtract halfSize from vectorSize giving restSize

         invoke vectorClass "new" using by value halfSize
                                  returning vectorv1
         invoke vectorClass "new" using by value restSize
                                  returning vectorv2
         move 0 to i
         perform until i = halfSize
             invoke vector "elementAt" using by value i
                                             returning atObj
             invoke vectorv1 "addElement" using by value atObj
             invoke atObj "finalize" returning atObj
             add 1 to i
         end-perform
         perform until i = vectorSize
             invoke vector "elementAt" using by value i
                                             returning atObj
             invoke vectorv2 "addElement" using by value atObj
             invoke atObj "finalize" returning atObj
             add 1 to i
         end-perform

      * Sort both halves of the vector
         invoke self "sortVector" using by value vectorv1
                                  by value compare
                                  returning sortResultA
         invoke self "sortVector" using by value vectorv2
                                  by value compare
                                  returning sortResultB
         if (vectorv1 not = sortResultA)
             invoke vectorv1 "finalize" returning vectorv1
         end-if
         if (vectorv2 not = sortResultB)
             invoke vectorv2 "finalize" returning vectorv2
         end-if

      * Merge the results
         invoke self "mergeVectors" using by value sortResultA
                                   by value sortResultB
                                   by value compare
                                   returning result

         if (result not = sortResultA)
             invoke SortResultA "finalize" returning SortResultA
         end-if
         if (result not = sortResultB)
             invoke SortResultB "finalize" returning SortResultB
         end-if
         exit method.
       end method "sortVector".

       method-id. "mergeVectors".
       local-storage section.
       01 totalSize pic x(4) comp-5.
       01 v1size pic x(4) comp-5.
       01 v2size pic x(4) comp-5.
       01 i pic x(4) comp-5.
       01 iCompare pic s9(9) comp-5.
       01 v1index pic x(4) comp-5.
       01 v2index pic x(4) comp-5.
       01 v1element object reference.
       01 v2element object reference.
       linkage section.
       01 vresult object reference.
       01 vectorv1 object reference.
       01 vectorv2 object reference.
       01 compare object reference.
       procedure division using by value vectorv1
                          by value vectorv2
                          by value compare 
                          returning vresult.
      *> If vector1 is NULL, return vector2 as the merged vector
         if (vectorv1 = null)
             set vresult to vectorv2
             exit method
         end-if

      *> If vector2 is NULL, return NULL as the merged vector
         if (vectorv2 = null)
             set vresult to null
             exit method
         end-if         

      *> Create a result vector with the total size of the two vectors
         invoke vectorv1 "size" returning v1size
         invoke vectorv2 "size" returning v2size
         add v1size to v2size giving totalSize
         invoke vectorClass "new" using by value totalSize
                                  returning vresult

       *> Merge the two vectors into the result vector
         move 0 to v1index
         move 0 to v2index
         move 0 to i
         perform until i = totalSize
           if (v1index = v1size)
       *>     v1 is finished, so add remaining v2 elements
              invoke vectorv2 "elementAt" using by value v2index
                                               returning v2element
              add 1 to v2index
              invoke vresult "addElement" using by value v2element
              invoke v2element "finalize" returning v2element
           else
              if (v2index = v2size)
       *>        v2 is finished, so add remaining v1 elements
                 invoke vectorv1 "elementAt" using by value v1index
                                                  returning v1element
                 add 1 to v1index
                 invoke vresult "addElement" using by value v1element
                 invoke v1element "finalize" returning v1element
              else
       *>        Get two elements from each vector and compare them
                 invoke vectorv1 "elementAt" using by value v1index
                                                  returning v1element
                 invoke vectorv2 "elementAt" using by value v2index
                                                  returning v2element
                 invoke compare "compare" using by value v1element
                                                by value v2element
                                                returning iCompare

       *>        Add the appropriate element to the result vector
                 if (iCompare <= 0)
                    add 1 to v1index
                    invoke vresult "addElement" using by value v1element
                 else
                    add 1 to v2index
                    invoke vresult "addElement" using by value v2element
                 end-if

                 invoke v1element "finalize" returning v1element
                 invoke v2element "finalize" returning v2element
              end-if
           end-if
           add 1 to i
         end-perform
         exit method.
       end method "mergeVectors".

       end object.
       end class SortDemo.
