From: Pete Dashwood on

"Richard" <riplin(a)Azonic.co.nz> wrote in message
news:1179977091.567546.22670(a)n15g2000prd.googlegroups.com...
> On May 23, 10:02 pm, "Pete Dashwood"
> <dashw...(a)removethis.enternet.co.nz> wrote:
>
>> It was Online Linking and Embedding (OLE). This then evolved into the
>> Common
>> Object Model.
>>
>> Fujitsu has supported it since version 3 which I acquired in 1997. It was
>> one of the first OO COBOL compilers. Fujitsu offered it free to people
>> who
>> were using MicroFocus COBOL.
>
> Version 3 did not have OO or OLE. As this version is still (? adtools
> has gone) available it may mislead students into think that it does.
>
> Version 4 introduced OO and OLE in 1998. I have both sets of paper
> manuals.
>
>
Thanks Richard. I thought it did but was wrong.

Pete.


From: Pete Dashwood on
Round of applause!!!

Really good stuff, Jimmy.

Some comments below...

"James J. Gavan" <jgavandeletethis(a)shaw.ca> wrote in message
news:EY85i.214410$6m4.184311(a)pd7urf1no...
> By George he's got it ! I think :-). Cut a long story short, I initially
> downloaded SOAP but doing that Registry check found I already had it.
> Whether or not that duplication was causing a problem ....???? Anyway
> deleted second.
>
> I keep on saying I code, (or used to code) in Classes so I have
> difficulty getting Procedurals to do exactly what I want without a lot of
> buggering around.

Not sure how you are using "Procedural" here.Maybe MF have a specific
meaning for it.

Example : I used '$set sourceformt "free"' and for
> some inexplicable reason the compiler queried your line numbers. I had
> other irritating problems as well. So sod it. Use what you are comfortable
> with. I went with the Class format - same as you did but now your
> paragraphs become methods. Here goes :-
>

I like what you did very much. I have reservations about trigger programs
but it works very well here.

> Give it a shot Rene and confirm that it works for you !
>
> The code for both starts in Column 8 -
>
> *>----------------- soaptrigger.cbl ----------------------------
>
> *> Trigger PROCEDURAL program used here. Assume Soaptest was
> *> selected from a Mster Menu - then the Menu would invoke in a
> *> similar manner.
>
> Program-id. SoapTrigger.
>
> Class-Control. SoapTest is class "soaptest".
>
> WORKING-STORAGE SECTION.
> 01 os-SoapTest object reference value null.
>
> PROCEDURE DIVISION.
>
> invoke SoapTest "new" returning os-SoapTest
> invoke os-SoapTest "begin"
> invoke os-Soaptest "finalize" returning os-SoapTest
>
> *> Strictly speaking the 'finalize' above is not required -
> *> it is replaced by the STOP RUN
>
> STOP RUN.
>
> *>--------------------------------------------------------------
>
>
> *>-----------------soaptest.cbl ------------------------------
> $set sourceformat"free"
> $set ooctrl(+p)
> *>------------------------------------------------------------
>
> *> Original Procedural program written by Peter E.C. Dashwood
> *> in May 2007 using Fujitsu dotNetCOBOL invoking Soap
>
> *> This class adapated by James J. Gavan for Net Express V 3.1.
> *> If using later versions of Net Express then REPOSITORY syntax
> *> can replace the 'Class-Control' entries below
>
> *>---------------------------------------------------------------
> Class-id. Soaptest.
> *> Soaptest inherits from Base.
>
> *> Where no inheritance is specified it defaults to Base
>
> Class-Control. *> olebase is class "olebase"
> oleexceptionmanager is class "oleexpt"
> Soaptest is class "soaptest"
> Mssoap is class "$OLE$MSSOAP.SoapClient30"
> .
>
> *> If having problems with OLE - you could use the N/E
> *> OleExceptionManager with a callback method - see N/E
> *> OO and OLE documentation
>
> *>--------------------------------------------------------------
> *> FACTORY.
> *> END-FACTORY.
> *>---------------------------------------------------------------
> OBJECT.
> *>---------------------------------------------------------------
> WORKING-STORAGE SECTION.
> 01 in-interface-block pic x(8197).
> 01 in-IB.
> 12 in-ws-return pic x(5).
> 88 in-ws-OK value '00000'. *> will contain SQLSTATE if
> *> there is a DB error
> 12 in-ws-message pic x(256). *> will contain SQLMSG if
> *> there is a DB error
> 12 in-ws-buffer pic x(2048). *> holds free format address
> *> this will be formatted on
>
> 12 in-ws-breakdown.
> 15 in-ws-streetNo pic x(20).
> 15 in-ws-POBoxNo pic x(15).
> 15 in-ws-RDNo pic x(8).
> 15 in-ws-street pic x(150).
> 15 in-ws-locality pic x(150).
> 15 in-ws-city pic x(50).
> 15 in-ws-lobby pic x(150).
> 15 in-ws-postCode pic x(4).
> 15 in-ws-addressType pic x(1).
> 15 in-ws-streetSDX pic x(4).
> 15 in-ws-localitySDX pic x(4).
> 15 in-ws-lobbySDX pic x(4).
> 15 in-ws-prologue pic x(100).
> 12 in-ws-interface pic x.
> 88 in-free-format-input value '1'.
> 88 fixed-field-input value '2'.
> 88 XML-input value '3'.
> 12 in-ws-streetMatchFlag pic x(1).
> 88 street-fuzzy value '0'.
> 88 street-exact value '1'.
> 12 in-ws-localityMatchFlag pic x(1).
> 88 locality-fuzzy value '0'.
> 88 locality-exact value '1'.
> 12 in-ws-repeatLocalityFlag pic x(1).
> 88 no-Locality value '1'.
> 88 repeatLocality value '0'.
> *> used if Locality = City
> 12 in-ws-ignoreInvalidPostcode pic x(1).
> 88 ignoreInvalidPostCode value '1'.
> 88 reportInvalidPostCode value '0'.
> *>stops if Post Code is invalid
> 12 in-ws-foreignFlag pic x(1).
> 88 foreign-address value '1'.
> *>stops if foreign address detected
> 88 NOT-foreign-address value '0'.
>
> 01 out-interface-block pic x(8197).
> 01 out-IB.
>
> 12 out-ws-return pic x(5).
> 88 out-ws-OK value '00000'.
> *> will contain SQLSTATE if
> *> there is a DB error
> 12 out-ws-message pic x(256). *> will contain SQLMSG if
> *> there is a DB error
> 12 out-ws-buffer pic x(2048).
> *> holds free format address data
> *> this will be formatted on return
> 12 out-ws-breakdown.
> 15 out-ws-streetNo pic x(20).
> 15 out-ws-POBoxNo pic x(15).
> 15 out-ws-RDNo pic x(8).
> 15 out-ws-street pic x(150).
> 15 out-ws-locality pic x(150).
> 15 out-ws-city pic x(50).
> 15 out-ws-lobby pic x(150).
> 15 out-ws-postCode pic x(4).
> 15 out-ws-addressType pic x(1).
> 15 out-ws-streetSDX pic x(4).
> 15 out-ws-localitySDX pic x(4).
> 15 out-ws-lobbySDX pic x(4).
> 15 out-ws-prologue pic x(100).
> 12 out-ws-interface pic x.
> 88 free-format-input value '1'.
> 88 fixed-field-input value '2'.
> 88 XML-input value '3'.
> 12 out-ws-streetMatchFlag pic x(1).
> 88 street-fuzzy value '0'.
> 88 street-exact value '1'.
> 12 out-ws-localityMatchFlag pic x(1).
> 88 locality-fuzzy value '0'.
> 88 locality-exact value '1'.
> 12 out-ws-repeatLocalityFlag pic x(1).
> 88 no-Locality value '1'.
> 88 repeatLocality value '0'.
> *> used if Locality = City
> 12 out-ws-ignoreInvalidPostcode pic x(1).
> 88 ignoreInvalidPostCode value '1'.
> 88 reportInvalidPostCode value '0'.
> *> stops if Post Code is invalid
> 12 out-ws-foreignFlag pic x(1).
> 88 foreign-address value '1'.
> *>stops if foreign address detected
> 88 NOT-foreign-address value '0'.
>
> *> OBJECTS.
>
> 01 objSoapClient object reference value null.
>
> *>--------------------------------------------------------------
> Method-id. "begin".
> *>--------------------------------------------------------------
> *>
> *> Interesting - I normally type :-
> *>
> *> invoke self (this instance) "startup-housekeeping"
> *>
> *> Guess the compiler knows I'm referring to 'self' !!!
>
> invoke "startup-housekeeping"
> invoke "main-logic"
> invoke "finalize-objects"
>
> End Method "begin".
> *>---------------------------------------------------------------
> Method-id. "startup-housekeeping".
> *>--------------------------------------------------------------
> WORKING-STORAGE SECTION. *> Only allowed in Net Express
>
> *>WSDL to connect to the remote host (in San Francisco)
>
> *> NOTE : The compiler will tell you if your value (66 below)
> *> doesn't equate to the size of the literal
>
> 01 WSDL-reference pic x(66) value
> z'http://primacomputing.co.nz/AVSWebService/AVSWebService.asmx?WSDL'.
>
> *> WSDL to connect to my IIS server on my new VAIO notebook
> *> machine over wireless LAN.
> *>
> *> 'http://bigblack/AVSWebService/AVSWebService.asmx?WSDL'.
> *>
> *>I have tested both of the above and they both work perfectly.
>
> invoke MSSOAP "new" returning objSoapClient
> invoke objSOAPClient "mssoapinit"
> using WSDL-reference
> End Method "startup-housekeeping".
> *>--------------------------------------------------------------
> Method-id. "main-logic".
> *>--------------------------------------------------------------
>
> move spaces to in-IB
> set in-free-format-input to TRUE
> *> move '97 21ST AVE TAURANGA' to in-ws-buffer *> A NZ address...
> move '48 35TH BLVD TOURONGA' to in-ws-buffer
>
> *> The commented address above is valid, whereas the second
> *> address being used is invalid
>
> move in-IB to in-interface-block
>
> *> Note that string parameters to COM objects must be 8197
> *> and must be elemental.
>
> invoke objSOAPClient "ValidateNZaddress"
> using in-interface-block *> input interface block
> returning out-interface-block *> output interface block
>
> *> Note that you could use just one block
> *> but you must reference it in and out because the
> *> Web Service expects in and out parameters
>
> invoke self "error-fix"
>
> *> Debugging Note
> *>
> *> Now is a good time to look at out-ws-breakdown and
> *> out-ws-buffer...
> *>
> *> If you are stepping through this in the debugger, note that each
> *> field has been filled in,
> *> (street number, street, locality, region, and postcode)
> *> and the ws-buffer area now contains a properly formatted address
> *> which complies with NZPO requirements, and has been converted
> *> to mixed case.
> *>
> *> out-ws-breakdown
> *> out-ws-buffer
>
> Exit Method. *> Exit-Method is only really required when you
> *> have a conditional EXIT. Here I'm using
> *> 'Exit Method' as an Animator breakpoint so that
> *> I can view the above two variables
>
> End Method "main-logic".
> *>--------------------------------------------------------------
> Method-id. "error-fix".
> *>--------------------------------------------------------------
> *>============== SOAP XML Stringing error fix
> *> There is currently a problem with SOAP stripping out certain
> *> characters in the returned string. This causes fields to be
> *> aligned incorrectly. The following is a quick fix and won't
> *> be required once the service is released.
> *>
>
> 01 J pic x(4) comp-5.
> 01 K pic x(4) comp-5.
>
> move 1 to K *> output buffer pointer
> perform
> varying J *> input buffer pointer (for this process)
> from 1
> by 1
> until K > function LENGTH (out-IB)
> move out-interface-block (J:1) to out-IB (K:1)
> add 1 to K
> if out-interface-block (J:1) = x'0A'
> move space to out-IB (K:1)
> add 1 to K
> end-if
> end-perform
>
> *>
> *>ALL of the above code would be replaced by:
> *>
> *> move out-interface-block to out-IB
> *>
> *>...once the COM server and SOAP wrapper are fixed. (I'm working
> *>on it... :-))
> *>
> End Method "error-fix".
> *>--------------------------------------------------------------
> method-id. "finalize-objects".
> *>---------------------------------------------------------------
>
> if ObjSoapClient <> null
> invoke ObjSoapClient "finalize" returning ObjSoapClient
> End-if
>
> End Method "finalize-objects".
> *>--------------------------------------------------------------
> END OBJECT.
>
> END CLASS SoapTest.
>
> *>---------------------------------------------------------------


This is really cool, Jimmy :-)

I was really pleased to see that my assessment was right and the mssoapinit
method didn't need the extra parameters. This works when the WSDL is
referenced from the web service itself, as we did.

It is a signal lesson in checking carefully what you get from the web; the
information offered was hopelessly out of date.

What I'd like to do is place the code in a 'downloads' directory on the
server, along with my Fujitsu version and any other versions that people
offer (maybe Java, C#, AcuCOBOL... whatever). As soon as I have time, I'll
write an article about the whole process and place that there too, so anyone
can see the story on accessing the service (or, indeed, any web service)
from COBOL, or anything else. If you have no objection to this, could you
mail me a zip of the MF project containing your code?

Finally, what was the response like? The first one would be a bit longer
because the DB buffers have to be loaded. Also, I currently use a new
instance of the service each time it is invoked and that takes time. I'm
looking into that; it gets a bit tricky with DB connections and connection
scope...

Thanks for spending the time to get this working, I'm sure a number of
people will use your code.

Pete


From: Pete Dashwood on

"James J. Gavan" <jgavandeletethis(a)shaw.ca> wrote in message
news:qZi5i.214632$DE1.57499(a)pd7urf2no...
> Pete Dashwood wrote:
>> Round of applause!!!
>>
>> Really good stuff, Jimmy.
>>
>> Some comments below...
>>
>
>> Not sure how you are using "Procedural" here.Maybe MF have a specific
>> meaning for it.
>
> Well you might not like it, but I would call your source 'Procedural' in
> that it is a PROGRAM source as opposed to a CLASS source, although you are
> still creating/accessing objects via invokes. I think the advantage of ALL
> classes is the ability to do a 'round robin' between the various classes
> because you can have an instance handle (object reference) to each. (My
> comment was not based on Micro Focus - they are silent on the topic).

OK, that's fair enough.

>
>> I like what you did very much. I have reservations about trigger programs
>> but it works very well here.
>>
> Well of course the early M/F OO examples all did/and still have a Trigger
> program. The main functions are :-
>
> - Menu driven application - from the Trigger start the App(Business Logic)
> and the Master Menu. Return handles from both to the Trigger which passes
> them to the corresponding App and Menu instances

Yes, I've read Wil Price's book. :-)

Similar things can happen with Fujitsu. For example, you may have a .EXE
that invokes methods from a .DLL. (And, in my case at least, the .DLL is
usually a COM Server.)

Of course, by encapsulating functionality into a COM Server, you don't need
a Trigger; it can be dropped and used almost anywhere that supports OO, not
just COBOL. This gets over the old grizzle we've always had about Class
interoperability (or the lack of it) in COBOL. I have Java, C#, COBOL, and
ASP all using OO Class methods and properties that are written in COBOL.
COM empowers this; Web Services take it even further by making it global.
(In the World sense, not the programming sense... :-))

I don't think it really matters what you call it.

>
> - call "apigui" which kick starts GUIing
>
> This is the trigger for the Corrosion Testing application, which
> illustrates above :-
>
> *>--------------------ctbegin.cbl--------------------------
>
> PROGRAM-ID. ctbegin.
>
> CLASS-CONTROL. ctApplication is class "ctapp"
> ctMenu is class "ctmenu"
> EventManager is class "p2emgr"
> Module is class "module"
> .
>
> *>--------------------------------------------------------------
> OBJECT-STORAGE SECTION.
> copy "\copylib\sqlResult.cpy" replacing ==(tag)== by ==01 ws==.
> 01 CtResourceID pic x(10) value z"ctres.dll".
>
> 01 os-App object reference.
> 01 os-Desktop object reference.
> 01 os-EventManager object reference.
> 01 os-Menu object reference.
> 01 os-Resource object reference.
>
> PROCEDURE DIVISION.
>
> call "apigui"
> invoke EventManager "new" returning os-EventManager
> invoke os-EventManager "initialize"
> invoke os-EventManager "getDesktop" returning os-Desktop
> invoke Module "newZ" using CtResourceID
> returning os-Resource
>
> invoke ctApplication "new" returning os-App
> invoke ctMenu "new" using os-Desktop
> returning os-Menu
>
> invoke os-App "passHandles" using os-Desktop
> os-Menu
> os-Resource
> invoke os-Menu "passHandles" using os-Desktop
> os-EventManager
> os-App
> os-Resource
> invoke os-Menu "createMenu"
> invoke os-Menu "create"
> invoke os-App "checkFiles" returning ws-SqlResult
>
>
> if ResultOK
> invoke os-Menu "show"
> invoke os-EventManager "run"
> End-if
>
>
> STOP RUN.
>
> *>--------------------------------------------------------------
>
>
> Now if you look at current M/F Dialog System examples they all start with
> a 'Procedural' which also tends to be the Business Logic. As it is
> Procedural they use entry-points to get at different Sections to handle
> results of different GUI events.
>
>> What I'd like to do is place the code in a 'downloads' directory on the
>> server, along with my Fujitsu version and any other versions that people
>> offer (maybe Java, C#, AcuCOBOL... whatever). As soon as I have time,
>> I'll write an article about the whole process and place that there too,
>> so anyone can see the story on accessing the service (or, indeed, any web
>> service) from COBOL, or anything else. If you have no objection to this,
>> could you mail me a zip of the MF project containing your code?
>
> No objections. I'll send you a zip.

Thanks.

>>
>> Finally, what was the response like? The first one would be a bit longer
>> because the DB buffers have to be loaded. Also, I currently use a new
>> instance of the service each time it is invoked and that takes time. I'm
>> looking into that; it gets a bit tricky with DB connections and
>> connection scope...
>>
> Mere seconds. To keep it simple I'll have the SoapTrigger invoke my
> DateTime Class, (which I'll also send), to get the Date/Time (pic x 21)
> for start of Trigger and end of Trigger.
>
> PS: Would you refer to your SoapTest.cbl as a standalone or would you
> categorize it as a component ?

Definitely a standalone. It is really just a "harness" for testing the proxy
Class. However the web service, although being around 4000 lines of OO COBOL
code, I would consider to be a component. (I don't plan on maintaining this
code, once it has completed all of its testing.) I can't publish the code as
it is commercially sensitive, but I can tell you it has three main methods
in the Class, which are supported by other smaller methods:

(Note, I have no qualms about describing these methods publicly, because
they cannot be accessed directly. Using a web service you decide what will
be exposed and what won't...)

1. ParseOnly.

This deals with stripping a free format address into words, and attempting
to locate what is a street, a locality or lobby, a region, and a postcode.
In my naivety I figured a COBOL UNSTRING would be the caper... I crashed and
burned :-) Here's the code that sets the input buffer up so it CAN be
unstrung into words...

*
* Prepare the data buffer...
* Get all words, separated by a single space
*
move zero to ws-return
move spaces to stored-inrec
move 1 to K
perform
varying J
from 1
by 1
until J > function STORED-CHAR-LENGTH (ws-buffer)
if NOT (ws-buffer (J:1) ALPHABETIC OR ws-buffer (J:1)
NUMERIC)
AND NOT (ws-buffer (J:1) = '&'
OR ws-buffer (J:1) = '-'
OR ws-buffer (J:1) = '/'
OR (ws-buffer (J:1) = "'"
AND ws-buffer (J + 2:1) NOT = space))
move space to ws-buffer (J:1)
if ws-buffer (J:1) = space AND
Function UPPER-CASE (ws-buffer (J + 1:2)) = "S
"
move ws-buffer (J + 1:2) to ws-buffer (J:2)
end-if
*> removes punctuation and line breaks
*> but allows &,-, ' (not apostrophe) and /
*> must allow "O'Neill" but not "Neil's"
end-if
if ws-buffer (J:1) NOT = space
move ws-buffer (J:1) to stored-inrec (K:1)
add 1 to K
set expecting-space to TRUE
else
if expecting-space
move ws-buffer (J:1) to stored-inrec (K:1)
add 1 to K
set NOT-expecting-space to TRUE
end-if
end-if
end-perform
*
* stored-inrec should now be a string of words separated by one
space...
*

(nothing is ever as easy as you think... :-) Today, I would write this in C#
using Regular Expressions, but the COBOL above serves well.)

2. FIB - Fill in the blanks

This makes sure that any missing address elements are located and validated
if they can be.

3. FormatAddress.

Places a correctly formatted address (in compliance with NZPO requirements)
into the returned buffer. It is constructed from the decomposed elements
provided by FIB.

So, 3 Major methods, 4000 lines of COBOL code, but the web service exposes
only one method (ValidateNZaddress). This is a method of the service itself
(which is also a Class and gets its own object instantiated). The service is
written in C# but it can use the COBOL Class because the COBOL Class is a
COM server. (So objects from almost ANY environment (including DotNET) can
invoke it).

This is my point about components. Encapsulating functionality into a COM
component (or a Web Service) means you have, in effect, "future proofed" it.
As long as you need that functionality, it is available, anywhere you want
it, any time you want it, as "pluggable" functionality.

Pete.



From: Pete Dashwood on

"James J. Gavan" <jgavandeletethis(a)shaw.ca> wrote in message
news:Z3n5i.215000$DE1.77290(a)pd7urf2no...
> Pete Dashwood wrote:
>
> Just in case you are itching to know runtimes based on following as
> modified, plus I also used your 'good address' :-
>
> *>----------------- soaptrigger.cbl ----------------------------
>
> *> Trigger PROCEDURAL program used here. Assume Soaptest was
> *> selected from a Mster Menu - then the Menu would invoke in a
> *> similar manner.
>
> Program-id. SoapTrigger.
>
> Class-Control. SoapTest is class "soaptest"
> DateAndTime is class "datetime"
> .
> WORKING-STORAGE SECTION.
> 01 os-SoapTest object reference value null.
> 01 os-DateTime object reference value null.
>
> 01 DateTime-start pic x(21).
> 01 DateTime-finish pic x(21).
>
> PROCEDURE DIVISION.
>
> invoke DateAndTime "new" returning os-DateTime
>
> invoke os-DateTime "getDateAndTime21"
> returning DateTime-start
> invoke SoapTest "new" returning os-SoapTest
> invoke os-SoapTest "begin"
> invoke os-DateTime "getDateAndTime21"
> returning DateTime-finish
>
> display "Soap Demo ccyymmddhhmmsshhGhhmm"
> display "Start of demo : " DateTime-start
> display "End of demo : " DateTime-finish
>
> STOP RUN.
>
> *>--------------------------------------------------------------
>
> Soap Demo Results :-
>
> Soap Demo ccyy mm dd hh mm ss hh G hhmm
> Start of demo : 2007 05 24 14 37 20 62 - 0700
> End of demo : 2007 05 24 14 37 21 89 - 0700
>
> Soap Demo ccyy mm dd hh mm ss hh G hhmm
> Start of demo : 2007 05 24 14 41 23 54 - 0700
> End of demo : 2007 05 24 14 41 24 60 - 0700
>
> Soap Demo ccyy mm dd hh mm ss hh G hhmm
> Start of demo : 2007 05 24 14 51 20 35 - 0700
> End of demo : 2007 05 24 14 51 21 78 - 0700

Thanks very much for that, Jimmy.

Always less than 1.5 seconds... acceptable. (I am working to improve it of
course.)

This matches the results I am getting here pretty closely, so the distances
don't seem to matter.

(I've seen local systems with worse performance than that, and some of those
were on mainframes (TSO...and CICS))

It's pretty amazing really that the Net can be that fast.

I'll be posting a batch demo to the site soon... :-)

Pete.

PS I read somewhere that it is necessary to have IIS installed in order to
run SOAP. I can't see why it would be, but can you confirm whether you have
it installed on your version of XP? (Home Edition doesn't have it, XP Pro
does not have it installed by default, you have to do it.)


From: Charles Hottel on

"Charles Hottel" <chottel(a)earthlink.net> wrote in message
news:%g45i.18421$3P3.8338(a)newsread3.news.pas.earthlink.net...
>
> "Pete Dashwood" <dashwood(a)removethis.enternet.co.nz> wrote in message
> news:5bhj8jF2rrq02U1(a)mid.individual.net...
>>
>> "Charles Hottel" <chottel(a)earthlink.net> wrote in message
>> news:6iM4i.12447$Ut6.3969(a)newsread1.news.pas.earthlink.net...
>>>
>> <snip>
>>>
>>> I have learned far more about OO from learning Java than from C++ or OO
>>> COBOL books. It is no silver bullet but I can see how it improves some
>>> things.
>>
>> Yes, I had exactly the same experience. OO is such an innate part of Java
>> that it just seems completely natural.
>>
>> For me, OO opens the way to component based design and programming. The
>> code posted in this thread is a concrete example of what I have been
>> talking about; the web service is simply a component exposed to the
>> Internet. You can plug it into your applications and not need to maintain
>> it or worry about it. (Conceptually it is just like an extension of the
>> OS; you use it every day and expect it to work as specified. It does what
>> it does.)
>>
>> Components may be the keys to the kingdom, unlocking Lamba functions and
>> functional programming and helping to move us toward Kurzweil's
>> Singularity.
>>
>> If you have a COBOL compiler on your home system, that supports OO, I
>> would urge you to try the code. (We will have a MicroFocus version any
>> time now, as well as the original Fujitsu NetCOBOL version which will
>> work with ANY version of Fujitsu COBOL, right back to version 3.)
>>
>> Why not attempt a Java Class to access it? (Kinda cool to have COBOL
>> being invoked by Java across thousands of miles :-))
>>
>> Researching how to access web services from Java is probably very useful
>> for both your Java and your web services learning.
>>
>> If you get stuck, I can help.
>>
<snip>

Well I made an attempt at invoking your web service from Java, but I did not
have much spare time so it was not completely successful.

I only have one book that talk about Java and web services: Just Java 2 6th
edition and it is a little dated (2004). Chapter 28, mostly talks about two
beta programs through Amazon ans Google. While they looked straightforward
enough I decided I did not have time for that approach.

There is also the Apache Axis package. I think when I have more time I will
try using it.

Basically they all process the WSDL and generate Java you can use in you
program to access the web servive.

I googled on "java invoke web service" and got more than 54 million hits
and there is lots of good stuff but most of it too long for the remaining
time I had left. At http://www.codeproject.com/soap/WSfromJava.asp I found
what looked like something short enough to try. It was a simple applet that
invoked a web service called ConcatWithSpace. It takes two string as input
and returns them concatenated with a space in the middle. One drawback is
it is for JDK 1.1. The entire web article is pretty short.

I downloaded the code, a Java program for the applet, which also has a
SoapRequestBuilder class, and a html page that invokes the applet and passes
the required parameters. I thought I could figure out the parms from your
WSDL and just change the web page to invoke your web service, but I must be
doing something wrong. I tried many variations but I always get: "Error:
access denied (java.net.SocketPermission)". Well I realize I am not
knowledgeable yet in this area of Java which is one reason for making the
attempt. Anyway I am sure this approach is not the best in general and Axis
is a better way to go. I see O''Reilly has a Java Web Services book. Just
what I need, another book added to my already very long list.

Here is the original html code for invoking the ConcatWithSpace service,
which I assume worked:

<HTML><HEAD>
<TITLE>Applet HTML Page</TITLE>
</HEAD>

<BODY>
<H3><HR WIDTH="100%">Applet HTML Page<HR WIDTH="100%"></H3>

<applet code="SOAPexample" width=400 height=50>
<param name="server" value="127.0.0.1">
<param name="method" value="ConcatWithSpace">
<param name="xmlnamespace" value="http://tempuri.org/">
<param name="webservicepath" value="/SimpleService/Service1.asmx">
<param name="string1" value="David">
<param name="string2" value="Hobbs">
</applet>

<HR WIDTH="100%">
</BODY></HTML>

Here is the modified version of the html:

<HTML><HEAD>
<TITLE>Applet HTML Page</TITLE>
</HEAD>

<BODY>
<H3><HR WIDTH="100%">Applet HTML Page<HR WIDTH="100%"></H3>

<applet code="SOAPexample" width=400 height=50>
<param name="server" value="http://primacomputing.co.nz/AVSWebService/">
<param name="method" value="ValidateNZAddress">
<param name="xmlnamespace"
value="http://primacomputing.co.nz/AVSWebService/">
<param name="webservicepath" value="/AVSWebService.asmx?WSDL">
<param name="string1" value="97 21ST AVE TAURANGA">
</applet>

<HR WIDTH="100%">
</BODY></HTML>

Here is the original Java code for the applet. I ran out of time ( I got
interrupted) before I could try to modify it. One change it needs for
certain is to comment out the logic for the second parameter being passed as
your web service only expects one input paramter. I did try running it
anyway in the hope that it would just ignore the second parameter. Perhaps
you or someone here can get it running. I am so sure that it is not the best
approach in general that I will wait until I can devote proper time to the
Axis approach. Well there might be even better ways, after all I am just a
couple hours into my investigations.

import java.applet.Applet;
import java.awt.*;
import java.net.*;
import java.util.*;
import java.io.*;

public class SOAPexample extends Applet {

private String response = "Nothing";

public void init() {
SoapRequestBuilder s = new SoapRequestBuilder();
s.Server = getParameter("server");
s.MethodName = getParameter("method");
s.XmlNamespace = getParameter("xmlnamespace");
s.WebServicePath = getParameter("webservicepath");
s.SoapAction = s.XmlNamespace+s.MethodName;
s.AddParameter("one", getParameter("string1"));
//s.AddParameter("two", getParameter("string2"));
response = s.sendRequest();
repaint();
}

public void paint(Graphics g) {
g.setColor(Color.black);
Font f = new Font("TimesRoman", 0, 20);
g.setFont(f);
g.drawString(response, 10, 20);
}

public void start() {
repaint();
}
}

class SoapRequestBuilder {
String Server = "";
String WebServicePath = "";
String SoapAction = "";
String MethodName = "";
String XmlNamespace = "";
private Vector ParamNames = new Vector();
private Vector ParamData = new Vector();

public void AddParameter(String Name, String Data) {
ParamNames.addElement( (Object) Name);
ParamData.addElement( (Object) Data);
}

public String sendRequest() {
String retval = "";
Socket socket = null;
try {
socket = new Socket(Server, 80);
}
catch (Exception ex1) {
return ("Error: "+ex1.getMessage());
}

try {
OutputStream os = socket.getOutputStream();
boolean autoflush = true;
PrintWriter out = new PrintWriter(socket.getOutputStream(),
autoflush);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.
getInputStream()));

int length = 295 + (MethodName.length() * 2) + XmlNamespace.length();
for (int t = 0; t < ParamNames.size(); t++) {
String name = (String) ParamNames.elementAt(t);
String data = (String) ParamData.elementAt(t);
length += name.length();
length += data.length();
}

// send an HTTP request to the web service
out.println("POST " + WebServicePath + " HTTP/1.1");
out.println("Host: localhost:80");
out.println("Content-Type: text/xml; charset=utf-8");
out.println("Content-Length: " + String.valueOf(length));
out.println("SOAPAction: \"" + SoapAction + "\"");
out.println("Connection: Close");
out.println();

out.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
out.println("<soap:Envelope
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
out.println("<soap:Body>");
out.println("<" + MethodName + " xmlns=\"" + XmlNamespace + "\">");
//Parameters passed to the method are added here
for (int t = 0; t < ParamNames.size(); t++) {
String name = (String) ParamNames.elementAt(t);
String data = (String) ParamData.elementAt(t);
out.println("<" + name + ">" + data + "</" + name + ">");
}
out.println("</" + MethodName + ">");
out.println("</soap:Body>");
out.println("</soap:Envelope>");
out.println();

// Read the response from the server ... times out if the response
takes
// more than 3 seconds
String inputLine;
StringBuffer sb = new StringBuffer(1000);

int wait_seconds = 3;
boolean timeout = false;
long m = System.currentTimeMillis();
while ( (inputLine = in.readLine()) != null && !timeout) {
sb.append(inputLine + "\n");
if ( (System.currentTimeMillis() - m) > (1000 * wait_seconds))
timeout = true;
}
in.close();

// The StringBuffer sb now contains the complete result from the
// webservice in XML format. You can parse this XML if you want to
// get more complicated results than a single value.

if (!timeout) {
String returnparam = MethodName + "Result";
int start = sb.toString().indexOf("<" + returnparam + ">") +
returnparam.length() + 2;
int end = sb.toString().indexOf("</" + returnparam + ">");

//Extract a singe return parameter
retval = sb.toString().substring(start, end);
}
else {
retval="Error: response timed out.";
}

socket.close();
}
catch (Exception ex) {
return ("Error: cannot communicate.");
}

return retval;
}
}


First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8
Prev: Microfocus Cobol "SLEEP" routine
Next: Help with Tcal