Quantcast
Channel: Visual COBOL
Viewing all articles
Browse latest Browse all 5819

Wiki Page: Visual COBOL 2.2 - JSP Web Services Tutorial

$
0
0
Document Support Material This document depends upon many different technologies. While it tries to cover the material as completely as possible it is not viable to present an exhaustive view of the topic. The material listed below references any extra material that is related to the topic. It should not be necessary to complete the tutorial but will make it easier to understand the material. Java - Java is used to implement our web service and call out to our COBOL code that implements the core functionality of the service. At least a rudimentary understanding of Java is required for this tutorial. Java Servlets - Java Servlets are the core technology in the Java Enterprise Edition stack for handling web services. This tutorial aims to demonstrate the reuse of traditional COBOL programs in a JVM JSP application. The tutorial will use Visual COBOL 2.2. Version 2.5 of the servlet API will be used. The tutorial will be created with Tomcat version 7 in mind though it will be possible to use it with any supported servlet container. To complete this application we will create a JVM COBOL project containing our traditional COBOL program. We will create an Eclipse Web Tool Platform (WTP) Dynamic Web project. This web project will call the COBOL program using the Micro Focus smart linkage facility. It will cover development and debugging of the application. We will create the JSP view and dispatch code in Java. The sole usage of COBOL will be in the original unchanged COBOL program. There is an attached source code archive for this tutorial. You can acquire it here . You should download this and store it on your machine. The location it is stored at will be referred to as SRC_DIR in this tutorial. First Time Setup If this is your first time doing this tutorial you will need to setup your environment to run JVM COBOL JSP applications. You will need to install and setup Micro Focus Visual COBOL for Eclipse 2.2. You also need to install your servlet container/Java Enterprise Edition server (Tomcat, JBoss, etc) and setup the Micro Focus JVM COBOL runtime to be accessible in that environment. Links to those steps are below: Micro Focus COBOL: Windows UNIX Servlet Containers Create Workspace The first thing you need to do is create the workspace that will contain all the projects. Open Micro Focus Visual COBOL for Eclipse and pick an appropriate path as the workspace when prompted (the tutorial will refer to this location as WORKSPACE or just as 'the workspace'). Click Ok and Eclipse will create the workspace at that location automatically if it doesn't already exist. We will be adding several projects to this workspace to create the application. JVM COBOL Project Firstly we will create a project to contain our procedural COBOL program and make it available for execution from a Java program. The steps to do this are as follows: Click File - New - Other. Expand the Micro Focus COBOL node and select COBOL JVM Project . Click Next . Set the Project name field to "CobolBook". Ensure Use default location is checked. Ensure that the JRE is set up to use a Java 6 VM. Click Finish . This will create a blank JVM COBOL project which can contain our procedural COBOL program and be imported into our web application later. If it asks you to switch to the COBOL perspective then do so. To change perspectives later you can click on the appropriate option in the top right of the Eclipse main window (see the image below). In general any action that uses the CobolBook project will be expected to be executed in the COBOL perspective unless otherwise specified. The dynamic web project that comes later will expect actions to be executed in the Java EE perspective. The Eclipse Perspective Bar One aspect of Java it is necessary to adapt our program to is the Java packaging system. By default COBOL programs will be placed in the default root Java package. JVM servlet containers do not always allow root package classes to be loaded so we will need to set up a package for our program. For reference the Java package system is equivalent to the JVM COBOL namespace system. These two terms are interchangeable. To do set up the package right click on src in the CobolBook project of the COBOL Explorer in the top left of Eclipse. Now select New- COBOL JVM Package . In the dialog insert the text "com.microfocus.book" into the Name text field. Click Finish to create the package. This will create a directory structure in our workspace in which we can store our COBOL program. If you have the source code attached to this project you can copy SRC_DIR /CobolBook/src/com/microfocus/book/book.cbl to the equivalent directory in WORKSPACE . You should also copy SRC_DIR /src/book-rec.cpy to the equivalent location in the workspace. If you do not have the source archive you can create these files as follows. Right click on src in the CobolBook project in the COBOL Explorer tab and select New- COBOL Copybook . Ensure the Containing project text box contains "CobolBook/src". If not alter it so it does. Then in the New file name text box enter "book-rec.cpy". Click finish to create the copybook. Now replace the entire content of the opened file with the text in book-rec.cpy . Similarly to create book.cbl right click on src/com/microfocus/book in the CobolBook project. Select New- COBOL Program . Ensure the Containing project text box contains "CobolBook/src" again. The Package text box should contain "com.microfocus.book". Enter "book.cbl" in the Name text box. Click finish to create the COBOL program. Now replace the entire content of the opened program with the text in book.cbl . Putting the program in the right directory structure is only half the requirement to put it in the right package. You need to alter the program to specify the correct namespace as a qualified program name. Alternatively you can set a compiler directive either globally to the project or in the program using the $set syntax. For this tutorial we will set a global compiler directive. We have only one program so no need for program specific directives. This also allows us to avoid altering our COBOL program. In other situations it may make more sense to make your programs use different namespaces. In that case you should use program local directives or a qualified program name. Regardless to set compiler directives open the project properties for CobolBook by right clicking on the CobolBook node and clicking Properties . Expand Micro Focus COBOL and choose Build Configuration . At the bottom there is a box which is labelled as Additional directives . Here we will enter our project global directives. Add the line "ilnamespace(com.microfocus.book)" to that text box. Click OK to save the new directives. This will now generate a COBOL program that is in the specified namespace. When you import this into Java the namespace will interact appropriately with Java packages. Now look in the directory bin/com/microfocus/book in the COBOL Explorer . In there you will see a BookLegacy.class and a BookLegacy.cbldat file. These together form your COBOL program specified by book.cbl. There is one other facility we will use to make life easier when calling the book demo program from Java. That is Micro Focus Smartlinkage. This is a tool that converts between traditional COBOL group item types and Java types. So a pic x(99) will be exposed as a Java String. A comp-5 item will become a Java int. This makes calling COBOL programs from Java much easier. There are three compiler directives we will be adding to support this. Add the compiler directive "ilsmartlinkage" on a new line in the Build Configuration dialog as before. If you save and close this configuration you will notice additional files in bin/com/microfocus/book . These are LnkBDetails.class , LnkFilename.class and LnkFileStatus.class . These are classes generated to represent the linkage items in our book.cbl program. The BookLegacy class will now have an entry point that takes these wrapper classes rather than just taking a generic reference class that gives direct byte access. This simplifies access. If you open book.cbl and hit F4 you will inline any copy books that are copied into this program. If you navigate down to the linkage section you will note the existence of the group items lnk-filename , lnk-file-status and lnk-b-details . These map directly onto the generated classes mentioned above. However we'd prefer to remove the prefixes commonly used in COBOL programs when working in Java. There is a directive to do this. Add the directives "ilcutprefix(lnk-b-)" and "ilcutprefix(lnk-)" to the Build Configuration . When you save and close the dialog your COBOL will be rebuilt. If you look in bin/com/microfocus/book once more you'll note that the prefixes have been removed from the generated class files. This finalises the JVM COBOL project and we will now move onto incorporating this into a web application. Dynamic Web Project Now we will create the JSP component of the application. This project will import the previous project as a dependency. It will be composed of in total: The CobolBook project. A JSP/Bean view that will form our web page. A wrapper interface that will manage our program's interaction with servlet session life cycles. A servlet class that will dispatch to that interface based upon the POST method arguments. A web.xml deployment descriptor. RunUnits and Sessions Before we continue it is useful to talk in more detail about point 3. Many COBOL applications may be single user programs. To adapt these programs into a multi user setting like a web application can be problematic. You will get issues like file locking and memory isolation breaking down because suddenly the same resource set is being used by multiple users. Usually fixing this requires a significant rewrite. Micro Focus has a better solution for this problem. We have a construct known as a RunUnit. This is specified by the JVM COBOL runtime class "com.microfocus.cobol.runtimeservices.RunUnit". Each RunUnit is a new session object. Each contains its own memory space and file lock table. A JVM COBOL program in one RunUnit will not normally access the memory of a program in another RunUnit. There is isolation between them. Also file locks are held per RunUnit. If a program in one RunUnit holds a file lock it will not be accessible to a file handling program in another RunUnit in the same process. This facility makes it easier for us to establish isolation between single user COBOL programs that are being migrated into a multi user environment. To further this we have the concept of a RunUnitManager. Each such manager is designed to manage the life cycle of RunUnit objects in environments with a notion of a session. A RunUnitManager provides a number of services: The creation of a RunUnit when a session starts. The retrieval of a RunUnit already attached to a session. Ensuring that a RunUnit is safelty stopped, and its resources cleaned up, when a session ends. Of particular relevance to this tutorial is the class "com.microfocus.cobol.runtimeservices.servlet.ServletRunUnitManager". This class in the JVM COBOL runtime is set up specifically to handle the life cycle of RunUnits in the context of servlet API HttpSession objects. Creating the Project The steps to create the dynamic web project are as follows: Click File- New- Other . Expand the Web node and select Dynamic Web Project . Click Next . Set the Project name field to "JSPBookDemo". Ensure Use default location is checked. In the Target runtime field either select an already existing servlet container runtime or set one up by clicking New Runtime . To set up a runtime appropriate to your servlet container see here . Set the Dynamic web module version to 2.5. Click Finish . This may ask you to open the Java EE perspective. Do so. As before all commands involving the JSPBookDemo will be expected in the Java EE perspective. Now we need to add appropriate references to the previous project and to the JVM COBOL runtime system. There are two places this must be done: in the build options, so the Java compiler can find the appropriate classes to build against; and in the deployment assembly so that the JVM COBOL program and runtime will be exported into the created web archive. To set up the Java Build Path complete the following: Open the project Properties for the JSPBookDemo as with the CobolBook project. Select Java Build Path . Select the Projects tab. Click the Add... button, check the CobolBook box and click OK . Select the Libraries tab. Click the Add Library... button, select COBOL JVM Runtime System , click Next and finally Finish . Now we need to set up the Deployment Assembly complete the following: In the Properties dialog select Deployment Assembly . Click Apply if asked to save any build path changes. Click Add , select Project and click Next . Select CobolBook and click Finish . Click Add , select Java Build Path Entries and click Next . Select COBOL JVM Runtime System and click Finish . Click OK to exit the Properties dialog. Creating the View The standard way to create a view in a JSP application is to have a JSP page that takes a Java bean (which is an ordinary Java data class) as an attribute. The JSP will then insert the properties from that bean into the appropriate places in the output HTML. Lets start with the JSP page. Right click on the WebContent node in the JSPBookDemo project. Select New- JSP File . Set the File name text box to say BookJsp.jsp. Finally click Finish . You can copy the contents of this file from BookJsp.jsp . If we look at BookJsp.jsp you will see numerous elements that contain text like ${book.stockno} . That states that the JSP will insert the value contained in the stockno property of the book attribute at this point. There are also other such elements like ${rununitid}. These are more direct text attributes that are not directly related to a book entry so have been kept separate. In this case we are passing in the RunUnit ID so we can display it in the title. Once all the ${} entries have been processed the JSP just becomes a simple HTML page containing a form. We will now create the book bean that goes along with this view. Right click on Java Resources and select New- Class . Enter the package "com.microfocus.book" and the class name "BookBean". Click Finish to create the BookBean class. Now enter the code in BookBean This class will contain the information that will be displayed in our JSP view. The dispatch servlet will bind an appropriate bean to the attribute book before calling the JSP. For instance in the previous book.stockno example it will call the getStockno method on BookBean and insert the return value into the JSP output. Converting Status Codes to Exceptions Error handling is very different in Java to procedural languages like COBOL. In Java it is normal to use exceptions rather than error codes to deal with failure and unexpected conditions. Given that our book demo returns a status code we need to convert this into an exception to make it a more natural fit for the JVM. Let's create our exception. As with the bean create a new Java class. Use the same package but call it JavaBookException. Change the superclass to be "java.lang.Exception". Enter the code in JavaBookException . This class is relatively simple. The serialVersionUId is used by the Java serialization mechanism to distinguish between different versions of a class. It has no impact on our program. We have a constructor that takes a String. The status item in the COBOL is a pic xx which will be mapped to a String in Java. So we are taking the status code directly in the constructor when converting the error. We have a Map String, String which relates known status codes to appropriate error messages. We also have a static String for unknown error in case something beyond the expected errors occurs. We pass on the appropriate error message to the superclass constructor and store the status code in a field. Creating the BookInterface The following class really is the most relevant to accessing JVM COBOL from a JSP web application. It will handle the session management and provide a clean interface to Java applications that wish to call the program. It will also handle marshalling between the view bean and the smart linkage Details class from the COBOL program. Firstly create a new Java class as before. Put it in the "com.microfocus.book" package. Give it the name BookInterface. Add the contents from BookInterface . This class is what will handle our session management and integration into a Java environment. Of particular interest are the two constructors listed below. public final IRunUnit runUnit; public final BookLegacy bookLegacy; public BookInterface(HttpSession session) { this(ServletRunUnitManager.getManager().GetSessionRunUnit(session)); } public BookInterface(IRunUnit runUnit) { this.runUnit = runUnit; BookLegacy bookLegacy = (BookLegacy) runUnit.GetInstance(BookLegacy.class); if(bookLegacy == null) { bookLegacy = new BookLegacy(); runUnit.Add(bookLegacy); } this.bookLegacy = bookLegacy; } These constructors handle two separate issues. The lower one handles tying this interface class into a RunUnit. It stores away the RunUnit and gets the program instance of BookLegacy. The upper constructor deals with the servlet's HttpSession object and the ServletRunUnitManager. The interaction here is quite simple. Get the ServletRunUnitManager (which is a singleton) and then call GetSessionRunUnit with the session object. The manager will create a RunUnit if this is the first call with this particular session. It will also manage the shutdown handling routines so that when this session is invalidated the manager will call StopRun on the RunUnit attached to that session. In this short section of code we've managed both the issue of program isolation and that of session life cycles. Not bad for a few lines of code in two constructors. Another interesting line of code is the BOOK_FILE constant near the top of the class. This constant specifies where the bookfile.dat file that contains our book database is on how hard drive. The relevant file is stored in the source archive attached to this tutorial. Store it somewhere on your local drive and update the constant to point to it. The rest of the code is pretty straight forward. We've split the function parameter into separate method calls on this interface. We also have some short code to handle whether we have an error or not. Creating the Servlet The last functional piece of code that needs to be written for this tutorial is the servlet that interprets the incoming POST and GET requests and dispatches to the appropriate interface method. It will then bind the output BookBean into the request and forward that request to the JSP for response. Create a new Java class as before. Put it in the "com.microfocus.book" package. Give it the name BookServlet. Add the contents from BookServlet . There are four interesting parts to this class. The interpretation of the appropriate POST parameters. The resulting calls into BookInterface. The binding of an output BookBean into the request attributes and finally forwarding the request onto our JSP so it can create the response. Lets look at some code in the doProcessing method. String subValue = req.getParameter(SUBMIT_PARAMETER); ... if(subValue.equals(READ_PARAMETER)) { performRead(req, res); } else if(subValue.equals(ADD_PARAMETER)) { performAdd(req, res); } else if(subValue.equals(DELETE_PARAMETER)) { performDelete(req, res); } This code simply grabs the value of the submit parameter from the request object. Then we compare the submit parameter to various known values that perform the appropriate functionality for each function the application provides. Now look in some detail at performRead . BookInterface bookInterface = getBookInterface(req.getSession()); String bookId = BookBean.getStockno(req, res); try { BookBean book = bookInterface.readBook(bookId); outputBook(req, res, book); } catch (JavaBookException e) { outputBookException(req, res, e); } catch (Exception e) { outputException(req, res, e); } This creates a BookInterface by passing in the session object from the request object. Then it gets the stock number from the request parameters. Then it makes a call to readBook on our interface. Finally outputting the BookBean object it gets back by calling outputBook . Lets examine that method. if(book != null) { req.setAttribute("book", book); } else { req.setAttribute("book", BookBean.msgBook("ERROR! book is null in output book")); } This very simply binds the book as a request attribute. Binding it to the name book which was the name used in our JSP view. The JSP will unpack this book object and output its values as described previously. The final part of interest is back in doProcessing RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(VIEW_URL); try { dispatcher.forward(req, res); } catch(Exception e) { throw new RuntimeException(e); } This gets a dispatch object for our view which is the BookJsp.jsp. Then it forwards the request to it. With all the necessary attributes set up this can output our book record correctly. The Deployment Descriptor (web.xml) There is one last file we need to modify before we have a complete web application. The deployment descriptor is the file used by the servlet container to define which servlets match up with which URLs. It also defines which servlet or resource provides the landing page for the root of the service. If it doesn't already exist create the file web.xml in the JSPBookDemo project. To do so right click on WebContent- WEB-INF then click New- File . Enter "web.xml" in the Filename text field and click Finish . Open the file and ensure it is in source mode by clicking the tab at the bottom left hand side of the editor window. Enter the content below. ?xml version="1.0" encoding="UTF-8"? web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5" display-name JSPBookDemo /display-name servlet servlet-name BookServlet /servlet-name servlet-class com.microfocus.book.BookServlet /servlet-class /servlet servlet-mapping servlet-name BookServlet /servlet-name url-pattern /view /url-pattern /servlet-mapping welcome-file-list welcome-file view /welcome-file /welcome-file-list /web-app This is a straight forward servlet deployment descriptor. The attributes for the web-app element are used to define the specific version of the servlet API in use. The display-name defines the internal name of this web application that will appear in the servlet container management system. The servlet element binds a name to a particular servlet class. In this case our BookServlet. The servlet-mapping element binds a particular servlet to a URL from the root of our servlet. So any call to say "localhost:8080/JSPBookDemo/view" will be directed to BookServlet. The last element is the welcome-file-list . This just defines a set of files that will be used as the landing page for the servlet. In this case we are setting the view to be our landing page. Running and Debugging Now that we have a complete application it is time to run it. To run it right click on JSPBookDemo in the explorer and select Run As- Run on Server . Eclipse will give you a window containing the servlet containers it knows about. Select the one you want to deploy to and click Finish . This will launch the servlet container, build our web application and deploy it to the server. It will then open up a web browser page displaying our application. To test it type in stock number "1111" and click Read . This should bring up the relevant book from the book file. To debug we should first set some break points. To set a breakpoint double click in the left hand margin of Eclipse next to a line you want to stop at. Set a break point in the servlet in the performRead call. Set another in the readBook method of the BookInterface. Set a third in book.cbl in the do-read-record section. To launch the debugger click the drop down arrow next to the debug icon on the tool bar (see image below). Then select Debug As and Debug on Server . If it asks to open the debug perspective let it do so. The Eclipse Debug Button When you get the interface popped up try to read book "1111" and it should hit your break points. Hit F8 to continue running. It should hit the following break points and eventually go from Java into the COBOL. Click the red box at the top left to stop the session. Appendix book.cbl ******************************************************************************************************** * * Copyright (C) Micro Focus (IP) Limited 2011. * All rights reserved. * * This sample code is supplied for demonstration purposes only on an "as is" basis and "is for use at * your own risk". * ******************************************************************************************************** $set retrylock program-id. BookLegacy. environment division. input-output section. file-control. select bookfile assign to filename file status is ls-file-status organization is indexed access mode is dynamic record key is b-stockno alternate record key is b-title with duplicates alternate record key is b-author with duplicates . data division. file section. FD bookfile. copy "book-rec.cpy" replacing ==(prefix)== by ==b==. working-storage section. 01 ls-file-status pic xx. 01 ls-call-status pic x(2) comp-5. linkage section. 01 lnk-filename pic x(256). 01 lnk-function pic x. 88 read-record value "1". 88 add-record value "2". 88 delete-record value "3". 88 next-record value "4". 01 lnk-file-status pic xx. 78 no-key-error value "B1". copy "book-rec.cpy" replacing ==(prefix)== by ==lnk-b==. procedure division using by value lnk-function by reference lnk-b-details by reference lnk-file-status. main section. call "CBL_TOUPPER" using lnk-b-text-details by value length lnk-b-text-details returning ls-call-status evaluate true when read-record perform do-read-record when add-record perform do-add-record when delete-record perform do-delete-record when next-record perform do-next-record end-evaluate exit program . do-read-record section. open input bookfile if ls-file-status "00" initialize lnk-b-details move all '*' to lnk-b-text-details move ls-file-status to lnk-file-status exit section end-if evaluate true when lnk-b-stockno spaces move lnk-b-stockno to b-stockno read bookfile when lnk-b-title spaces move lnk-b-title to b-title read bookfile key is b-title when lnk-b-author spaces move lnk-b-author to b-author read bookfile key is b-author when other * ------------No key specified - return unsuccessful read move no-key-error to ls-file-status end-evaluate move ls-file-status to lnk-file-status if ls-file-status = "00" move b-title to lnk-b-title move b-type to lnk-b-type move b-author to lnk-b-author move b-stockno to lnk-b-stockno move b-isbn to lnk-b-isbn move b-retail to lnk-b-retail move b-onhand to lnk-b-onhand move b-sold to lnk-b-sold else initialize lnk-b-details move all '*' to lnk-b-text-details end-if close bookfile . do-next-record section. open input bookfile if ls-file-status "00" initialize lnk-b-details move all '*' to lnk-b-text-details move ls-file-status to lnk-file-status exit section end-if move lnk-b-stockno to b-stockno start bookfile key b-stockno read bookfile next move ls-file-status to lnk-file-status if ls-file-status = "00" move b-title to lnk-b-title move b-type to lnk-b-type move b-author to lnk-b-author move b-stockno to lnk-b-stockno move b-isbn to lnk-b-isbn move b-retail to lnk-b-retail move b-onhand to lnk-b-onhand move b-sold to lnk-b-sold else initialize lnk-b-details move all '*' to lnk-b-text-details end-if close bookfile . do-add-record section. open i-o bookfile evaluate ls-file-status when "05" * -------File not created yet when "00" continue when other move ls-file-status to lnk-file-status exit section end-evaluate move lnk-b-stockno to b-stockno read bookfile if ls-file-status = "00" * Record already exists - so error move "99" to ls-file-status else move lnk-b-isbn to b-isbn move lnk-b-title to b-title move lnk-b-type to b-type move lnk-b-author to b-author move lnk-b-retail to b-retail move lnk-b-onhand to b-onhand move lnk-b-sold to b-sold write b-details end-if move ls-file-status to lnk-file-status close bookfile . do-delete-record section. open i-o bookfile if ls-file-status "00" move ls-file-status to lnk-file-status exit section end-if evaluate true when lnk-b-stockno spaces move lnk-b-stockno to b-stockno read bookfile delete bookfile record when lnk-b-title spaces move lnk-b-title to b-title read bookfile key is b-title delete bookfile record when lnk-b-author spaces move lnk-b-author to b-author read bookfile key is b-author delete bookfile record when other * ------------No key specified - return unsuccessful read move no-key-error to ls-file-status end-evaluate move ls-file-status to lnk-file-status close bookfile . set-filename section. entry "SET_FILENAME" using lnk-filename. move lnk-filename to filename goback. book-rec.cpy ****************************************************************** * * Copyright (C) Micro Focus 2010-2012. All rights reserved. * * This sample code is supplied for demonstration purposes only * on an "as is" basis and is for use at your own risk. * ****************************************************************** 01 (prefix)-details. 03 (prefix)-text-details. 05 (prefix)-title pic x(50). 05 (prefix)-type pic x(20). 05 (prefix)-author pic x(50). 03 (prefix)-stockno pic x(4). 03 (prefix)-isbn pic 9(13). 03 (prefix)-retail pic 99v99. 03 (prefix)-onhand pic 9(5). 03 (prefix)-sold pic 9(5) comp-3. BookBean.java package com.microfocus.book; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BookBean { private final String _stockno; private final String _isbn; private final String _title; private final String _author; private final String _type; private final String _price; private final String _onhand; private final String _sold; private final String _stockval; public static final String STOCK_NO_ATTRIBUTE = "stockno"; public static final String TITLE_ATTRIBUTE = "title"; public static final String AUTHOR_ATTRIBUTE = "author"; public static final String TYPE_ATTRIBUTE = "type"; public static final String ISBN_ATTRIBUTE = "isbn"; public static final String PRICE_ATTRIBUTE = "price"; public static final String ONHAND_ATTRIBUTE = "onhand"; public static final String SOLD_ATTRIBUTE = "sold"; private static final String ERROR_VALUE = "ERROR"; BookBean(String stockno, String isbn, String title, String author, String type, String price, String onhand, String sold, String stockval) { this._stockno = stockno; this._isbn = isbn; this._title = title; this._author = author; this._type = type; this._price = price; this._onhand = onhand; this._sold = sold; this._stockval = stockval; } public String getStockno() { return _stockno; } public String getIsbn() { return _isbn; } public String getTitle() { return _title; } public String getAuthor() { return _author; } public String getType() { return _type; } public String getPrice() { return _price; } public String getOnhand() { return _onhand; } public String getSold() { return _sold; } public String getStockval() { return _stockval; } public static BookBean blankBook() { return msgBook("*************************************"); } public static BookBean msgBook(String msg) { String stockno = "****"; String isbn = "*************"; String title = msg; String author = "*************************************"; String type = "****"; String price = "****"; String onhand = "****"; String sold = "****"; String stockval = "****"; return new BookBean(stockno, isbn, title, author, type, price, onhand, sold, stockval); } public static BookBean getBook(HttpServletRequest req, HttpServletResponse res) { return new BookBean(getStockno(req, res), getIsbn(req, res), getTitle(req, res), getAuthor(req, res), getType(req, res), getPrice(req, res), getOnhand(req, res), getSold(req, res), ""); } private static String getAttribute(HttpServletRequest req, HttpServletResponse res, String attribute) { String stockNoStr; stockNoStr = req.getParameter(attribute); if (stockNoStr == null) { stockNoStr = ERROR_VALUE; } return stockNoStr; } public static String getStockno(HttpServletRequest req, HttpServletResponse res) { String output = getAttribute(req, res, BookBean.STOCK_NO_ATTRIBUTE); if (output == null) { output = ERROR_VALUE; } return output; } private static String getTitle(HttpServletRequest req, HttpServletResponse res) { return getAttribute(req, res, BookBean.TITLE_ATTRIBUTE); } private static String getAuthor(HttpServletRequest req, HttpServletResponse res) { return getAttribute(req, res, BookBean.AUTHOR_ATTRIBUTE); } private static String getType(HttpServletRequest req, HttpServletResponse res) { return getAttribute(req, res, BookBean.TYPE_ATTRIBUTE); } private static String getIsbn(HttpServletRequest req, HttpServletResponse res) { return getAttribute(req, res, BookBean.ISBN_ATTRIBUTE); } private static String getPrice(HttpServletRequest req, HttpServletResponse res) { return getAttribute(req, res, BookBean.PRICE_ATTRIBUTE); } private static String getOnhand(HttpServletRequest req, HttpServletResponse res) { return getAttribute(req, res, BookBean.ONHAND_ATTRIBUTE); } private static String getSold(HttpServletRequest req, HttpServletResponse res) { return getAttribute(req, res, BookBean.SOLD_ATTRIBUTE); } } BookInterface.java package com.microfocus.book; import javax.servlet.http.HttpSession; import com.microfocus.cobol.program.IObjectControl; import com.microfocus.cobol.program.ScaledInteger; import com.microfocus.cobol.runtimeservices.IRunUnit; import com.microfocus.cobol.runtimeservices.servlet.ServletRunUnitManager; public class BookInterface { private static final String READ_RECORD = "1"; private static final String ADD_RECORD = "2"; private static final String DELETE_RECORD = "3"; private static final String NEXT_RECORD = "4"; private final IRunUnit runUnit; private final BookLegacy bookLegacy; private static final String BOOK_FILE = "C:/work/JavaWebServicesDemos/COBOLJSPDemo/CobolBook/bookfile.dat"; public BookInterface(HttpSession session) { this(ServletRunUnitManager.getManager().GetSessionRunUnit(session)); } public BookInterface(IRunUnit runUnit) { this.runUnit = runUnit; BookLegacy bookLegacy = (BookLegacy) runUnit.GetInstance(BookLegacy.class); if (bookLegacy == null) { bookLegacy = new BookLegacy(); runUnit.Add(bookLegacy); } this.bookLegacy = bookLegacy; } public BookBean readBook(String stockNo) throws JavaBookException { setFileName(BOOK_FILE); Details details = getObject(Details.class); FileStatus status = getObject(FileStatus.class); details.setStockno(stockNo); bookLegacy.BookLegacy(READ_RECORD, details, status); throwExceptionIfError(status); return bookBeanFromDetails(details); } public BookBean addBook(BookBean book) throws JavaBookException { setFileName(BOOK_FILE); Details details = getObject(Details.class); FileStatus status = getObject(FileStatus.class); bookBeanToDetails(book, details); bookLegacy.BookLegacy(ADD_RECORD, details, status); throwExceptionIfError(status); return bookBeanFromDetails(details); } public BookBean deleteBook(String stockNo) throws JavaBookException { setFileName(BOOK_FILE); Details details = getObject(Details.class); FileStatus status = getObject(FileStatus.class); details.setStockno(stockNo); bookLegacy.BookLegacy(DELETE_RECORD, details, status); throwExceptionIfError(status); return bookBeanFromDetails(details); } public BookBean nextBook(String stockNo) throws JavaBookException { setFileName(BOOK_FILE); Details details = getObject(Details.class); FileStatus status = getObject(FileStatus.class); details.setStockno(stockNo); bookLegacy.BookLegacy(NEXT_RECORD, details, status); throwExceptionIfError(status); return bookBeanFromDetails(details); } private void setFileName(String filename) { bookLegacy.SET_FILENAME(getFilenameObject(filename)); } private static void bookBeanToDetails(BookBean bean, Details details) { details.setStockno(bean.getStockno()); details.setIsbn(Long.parseLong(bean.getIsbn())); details.setTitle(bean.getTitle()); details.setAuthor(bean.getAuthor()); details.setType(bean.getType()); details.setRetail(ScaledInteger.parseScaledInteger(bean.getPrice())); int onHandInt = Integer.parseInt(bean.getOnhand()); if (onHandInt 0) throw new RuntimeException( "The number of books on hand must be 0 or positive"); details.setOnhand(onHandInt); int soldInt = Integer.parseInt(bean.getSold()); if (soldInt 0) throw new RuntimeException( "The number of books sold must be 0 or positive"); details.setSold(soldInt); } private static BookBean bookBeanFromDetails(Details details) { String stockno = details.getStockno().trim(); String isbn = "" + details.getIsbn(); String title = details.getTitle().trim(); String author = details.getAuthor().trim(); String type = details.getType().trim(); String price = details.getRetail().toString(); String onhand = "" + details.getOnhand(); String sold = "" + details.getSold(); ScaledInteger stockvalInt = details.getRetail().multiply( new ScaledInteger(details.getOnhand(), 0)); String stockval = stockvalInt.toString(); return new BookBean(stockno, isbn, title, author, type, price, onhand, sold, stockval); } private static void throwExceptionIfError(FileStatus statusCode) throws JavaBookException { throwExceptionIfError(statusCode.getFileStatus().trim()); } private static void throwExceptionIfError(String statusCode) throws JavaBookException { if (!"00".equals(statusCode) && !"02".equals(statusCode)) { throw new JavaBookException(statusCode); } } private Filename getFilenameObject(String filename) { Filename output = getObject(Filename.class); output.setFilename(filename); return output; } private T extends IObjectControl T getObject(Class T cls) { try { T output = cls.newInstance(); runUnit.Add(output); return output; } catch (Throwable t) { throw new RuntimeException(t); } } } BookServlet.java package com.microfocus.book; import java.io.PrintWriter; import java.io.StringWriter; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.microfocus.cobol.runtimeservices.IRunUnit; import com.microfocus.cobol.runtimeservices.servlet.ServletRunUnitManager; public class BookServlet extends HttpServlet { /** * */ private static final long serialVersionUID = -3563065100184185678L; public static final String STATUS_ATTRIBUTE = "status"; public static final String RUN_UNIT_ID_ATTRIBUTE = "rununitid"; public static final String SUBMIT_PARAMETER = "submit"; public static final String READ_PARAMETER = "Read"; public static final String ADD_PARAMETER = "Add"; public static final String DELETE_PARAMETER = "Delete"; public static final String NEXT_PARAMETER = "Next"; public static final String END_PARAMETER = "End Session"; public static final String DEFAULT_VALUE = "DEFAULT"; public static final String VIEW_URL = "/BookJsp.jsp"; protected void doProcessing(HttpServletRequest req, HttpServletResponse res, boolean isGet) { String subValue = req.getParameter(SUBMIT_PARAMETER); if (subValue == null) { subValue = DEFAULT_VALUE; } setRunUnitId(req); if (subValue.equals(READ_PARAMETER)) { performRead(req, res); } else if (subValue.equals(ADD_PARAMETER)) { performAdd(req, res); } else if (subValue.equals(DELETE_PARAMETER)) { performDelete(req, res); } else if (subValue.equals(NEXT_PARAMETER)) { performNext(req, res); } else if (subValue.equals(END_PARAMETER)) { performEndSession(req, res); } else { outputBlankBook(req, res); } RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( VIEW_URL); try { dispatcher.forward(req, res); } catch (Exception e) { throw new RuntimeException(e); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) { doProcessing(req, res, true); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse res) { doProcessing(req, res, false); } private void performRead(HttpServletRequest req, HttpServletResponse res) { BookInterface bookInterface = getBookInterface(req.getSession()); String bookId = BookBean.getStockno(req, res); try { BookBean book = bookInterface.readBook(bookId); outputBook(req, res, book); } catch (JavaBookException e) { outputBookException(req, res, e); } catch (Exception e) { outputException(req, res, e); } } private void performAdd(HttpServletRequest req, HttpServletResponse res) { BookInterface bookInterface = getBookInterface(req.getSession()); try { BookBean book = BookBean.getBook(req, res); book = bookInterface.addBook(book); outputBook(req, res, book); } catch (JavaBookException e) { outputBookException(req, res, e); } catch (Exception e) { outputException(req, res, e); } } private void performDelete(HttpServletRequest req, HttpServletResponse res) { BookInterface bookInterface = getBookInterface(req.getSession()); String bookId = BookBean.getStockno(req, res); try { BookBean book = bookInterface.deleteBook(bookId); outputBook(req, res, book); } catch (JavaBookException e) { outputBookException(req, res, e); } catch (Exception e) { outputException(req, res, e); } } private void performNext(HttpServletRequest req, HttpServletResponse res) { BookInterface bookInterface = getBookInterface(req.getSession()); String bookId = BookBean.getStockno(req, res); try { BookBean book = bookInterface.nextBook(bookId); outputBook(req, res, book); } catch (JavaBookException e) { outputBookException(req, res, e); } catch (Exception e) { outputException(req, res, e); } } private void performEndSession(HttpServletRequest req, HttpServletResponse res) { HttpSession session = req.getSession(); session.invalidate(); outputError(req, res, "Session invalidated"); } private void outputBlankBook(HttpServletRequest req, HttpServletResponse res) { outputBook(req, res, BookBean.blankBook()); } private void outputBookException(HttpServletRequest req, HttpServletResponse res, JavaBookException jbe) { outputError(req, res, jbe.getMessage()); } private void outputException(HttpServletRequest req, HttpServletResponse res, Exception e) { String msg = e.getClass().getName() + " [" + e.getMessage() + "]"; StringWriter strWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(strWriter); e.printStackTrace(printWriter); req.setAttribute(STATUS_ATTRIBUTE, strWriter.toString()); outputError(req, res, msg); } private void outputBook(HttpServletRequest req, HttpServletResponse res, BookBean book) { if (book != null) { req.setAttribute("book", book); } else { req.setAttribute("book", BookBean.msgBook("ERROR! book is null in output book")); } } private void outputError(HttpServletRequest req, HttpServletResponse res, String msg) { outputBook(req, res, BookBean.msgBook(msg)); } private IRunUnit getRunUnit(HttpSession session) { return ServletRunUnitManager.getManager().GetSessionRunUnit(session); } private void setRunUnitId(HttpServletRequest req) { HttpSession session = req.getSession(); IRunUnit runUnit = getRunUnit(session); String ruid = "" + runUnit.getRunUnitID(); req.setAttribute(RUN_UNIT_ID_ATTRIBUTE, ruid); } private BookInterface getBookInterface(HttpSession session) { BookInterface output = new BookInterface(session); return output; } } JavaBookException.java package com.microfocus.book; import java.util.*; public class JavaBookException extends Exception { /** * */ private static final long serialVersionUID = -3882735817601888938L; private static final Map String, String messages; private static final String unknownErrorMessage = "Unknown Error: "; public final String statusCode; public JavaBookException(String statusCode) { super(messages.containsKey(statusCode) ? messages.get(statusCode) : unknownErrorMessage + statusCode); this.statusCode = statusCode; } static { messages = new HashMap String, String (); messages.put("35", "Error: Data file not found"); messages.put("23", "Error: Stock item not found"); messages.put("46", "No more items left"); messages.put("99", "Error: Item already exists"); messages.put("01", "Error: File error"); messages.put("B1", "Error: No key entered"); } } BookJsp.jsp %@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"% !DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" html head meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" title JSP Book Demo - Run Unit ID: ${rununitid} /title /head body form name="input" action="/JSPBookDemo/view" method="post" table border="0" tr td Stock Number: /td td colspan="7" input type="text" name="stockno" value="${book.stockno}"/ /td /tr tr td ISBN: /td td colspan="7" input type="text" name="isbn" value="${book.isbn}"/ /td /tr tr td Title: /td td colspan="7" input type="text" size="120" name="title" value="${book.title}"/ /td /tr tr td Author: /td td colspan="7" input type="text" size="120" name="author" value="${book.author}"/ /td /tr tr td Type: /td td colspan="7" input type="text" size="120" name="type" value="${book.type}"/ /td /tr tr td Price: /td td input type="text" name="price" value="${book.price}"/ /td td On Hand: /td td input type="text" name="onhand" value="${book.onhand}"/ /td td Sold: /td td input type="text" name="sold" value="${book.sold}"/ /td td Stock Value: /td td input type="text" readonly="readonly" name="stockval" value="${book.stockval}"/ /td /tr tr td colspan="8" input type="submit" name="submit" value="Read" / input type="submit" name="submit" value="Add" / input type="submit" name="submit" value="Delete" / input type="submit" name="submit" value="Next" / input type="submit" name="submit" value="End Session" / /td /tr !-- tr td Status: /td td colspan="7" ${status} /td /tr -- /table /form /body /html

Viewing all articles
Browse latest Browse all 5819

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>