(under construction)
with GNAT.Regexp; with GNAT.Calendar.Time_IO; with Ada.Calendar; with Ada.Exceptions; 5with Ada.Text_IO; with Ada.Text_IO.Editing; with Ada.Characters.Latin_9; with AWS.Dispatchers.Callback; 10with AWS.Messages; with AWS.MIME; with AWS.Parameters; with AWS.Response; with AWS.Session; 15with AWS.Status; with AWS.Templates; with Bookstore.Books; with Bookstore.Carts; 20with Bookstore.Cart_Items; with Bookstore.Cart_Items.Lists; with Bookstore.Exceptions; with Bookstore.Messages.Localize; 25with Bookstore_2.Book_DAO; package body Bookstore_2.Requests_Processing is package Msg renames Bookstore.Messages.Localize; 30 -- -- todo : catch exceptions raised by book_dao -- 35 ---------------------- -- constant strings -- ---------------------- -- prefixes used in url 40 Image_Web_Prefix : constant String := "/images/"; Page_Web_Prefix : constant String := "/books/"; -- prefixes used internally 45 Image_Local_Prefix : constant String := "web/img/"; Page_Local_Prefix : constant String := "web/books/"; -- images names 50 Image_Adains_Name : constant String := "adains.png"; Image_Aws_Logo_Name : constant String := "aws_logo.png"; -- pages names 55 Store : constant String := "bookstore"; Catalog : constant String := "bookcatalog"; Details : constant String := "bookdetails"; Showcart : constant String := "bookshowcart"; 60 Cashier : constant String := "bookcashier"; Receipt : constant String := "bookreceipt"; -- extension used for template files Ext : constant String := ".thtml"; 65 -------------------------- -- web pages processing -- -------------------------- 70 -- welcome page function Page_Store (Request : in AWS.Status.Data) return AWS.Response.Data; -- all books function Page_Catalog (Request : in AWS.Status.Data) 75 return AWS.Response.Data; -- data about a book function Page_Details (Request : in AWS.Status.Data) return AWS.Response.Data; 80 -- cart content function Page_Showcart (Request : in AWS.Status.Data) return AWS.Response.Data; 85 -- form to buy function Page_Cashier (Request : in AWS.Status.Data) return AWS.Response.Data; -- receipt send after buying 90 function Page_Receipt (Request : in AWS.Status.Data) return AWS.Response.Data; ---------------------- -- image processing -- 95 ---------------------- function Image_Adains (Request : in AWS.Status.Data) return AWS.Response.Data; 100 function Image_Aws_Logo (Request : in AWS.Status.Data) return AWS.Response.Data; function Process_Image (Image : in String) return AWS.Response.Data; 105 ----------------------- -- Unknown_Resources -- ----------------------- function Unknown_Resources 110 (Request : in AWS.Status.Data) return AWS.Response.Data; ------------- -- Process -- ------------- 115 procedure Process (H : in out AWS.Services.Dispatchers.URI.Handler) is package URI renames AWS.Services.Dispatchers.URI; 120 begin -- dispatches requests for web pages URI.Register_Regexp (H, Page_Web_Prefix & Store & ".*", 125 Page_Store'Access); URI.Register_Regexp (H, Page_Web_Prefix & Cashier & ".*", Page_Cashier'Access); URI.Register_Regexp (H, Page_Web_Prefix & Catalog & ".*", Page_Catalog'Access); 130 URI.Register_Regexp (H, Page_Web_Prefix & Details & ".*", Page_Details'Access); URI.Register_Regexp (H, Page_Web_Prefix & Showcart & ".*", Page_Showcart'Access); URI.Register_Regexp (H, Page_Web_Prefix & Receipt & ".*", 135 Page_Receipt'Access); -- dispatches requests for images URI.Register (H, Image_Web_Prefix & Image_Adains_Name, 140 Image_Adains'Access); URI.Register (H, Image_Web_Prefix & Image_Aws_Logo_Name, Image_Aws_Logo'Access); -- unknown resources 145 URI.Register_Default_Callback (H, AWS.Dispatchers.Callback.Create (Unknown_Resources'Access)); end Process; 150 --------------------------------- -- used for session management -- --------------------------------- package Session_Cart is new AWS.Session.Generic_Data 155 (Data => Bookstore.Carts.Shopping_Cart, Null_Data => Bookstore.Carts.Empty_Cart); use Bookstore.Messages; -- xxx_key 160 ---------------- -- Page_Store -- ---------------- 165 function Page_Store (Request : in AWS.Status.Data) return AWS.Response.Data is Book_ID : constant String := "203"; -- id used in the web page 170 B : constant Bookstore.Books.Book := Book_DAO.Get_Book (Book_ID); use AWS.Templates; -- function Assoc use Bookstore.Books.Strings; -- function To_String 175 Translations : constant AWS.Templates.Translate_Table := (Assoc ("LANG", "en"), -- used by header.thtml Msg.Association (What_Key), Msg.Association (Talk_Key), Assoc ("BOOK_TITLE", To_String (B.Get_Title)), 180 Msg.Association (Start_Key)); begin return AWS.Response.Build (AWS.MIME.Text_Html, 185 String '(AWS.Templates.Parse (Page_Local_Prefix & Store & Ext, Translations))); end Page_Store; ------------------ 190 -- page_catalog -- ------------------ function Page_Catalog (Request : in AWS.Status.Data) return AWS.Response.Data is 195 Session_ID : constant AWS.Session.ID := AWS.Status.Session (Request); Translations : AWS.Templates.Translate_Set; use AWS.Templates; -- procedure Insert 200 -- function Assoc begin Add_Book: -- if the url has the parameter 'Add', there's a book to buy declare 205 P : constant AWS.Parameters.List := AWS.Status.Parameters (Request); Cart : Bookstore.Carts.Shopping_Cart := Session_Cart.Get (Session_ID, "cart"); Book : Bookstore.Books.Book; 210 use Bookstore.Books.Strings; -- function To_String begin if P.Exist ("Add") and then P.Get ("Add") /= "" then Book := Book_DAO.Get_Book (P.Get ("Add")); Cart.Add (Book.Get_ID, Book); 215 Session_Cart.Set (Session_ID, "cart", Cart); Insert (Translations, Msg.Association (Cart_Added_1_Key)); Insert (Translations, Msg.Association (Cart_Added_2_Key)); Insert (Translations, Assoc 220 ("ADDED_BOOK_TITLE", To_String (Book.Get_Title))); end if; end Add_Book; Get_Cart: -- gets the size of the cart 225 declare Cart : constant Bookstore.Carts.Shopping_Cart := Session_Cart.Get (Session_ID, "cart"); begin Insert (Translations, Msg.Association (Cart_Check_Key)); 230 Insert (Translations, Msg.Association (Buy_Key)); Insert (Translations, Assoc ("SIZE_OF_CART", Integer (Cart.Get_Number_Of_Items))); end Get_Cart; 235 Get_All_Books: -- retrieves data of all books declare Books_ID : AWS.Templates.Vector_Tag; Books_Title : AWS.Templates.Vector_Tag; Books_Price : AWS.Templates.Vector_Tag; 240 Books_First_Name : AWS.Templates.Vector_Tag; Books_Surname : AWS.Templates.Vector_Tag; All_Books : constant Bookstore.Books.Book_Array := Book_DAO.Get_Books; 245 use type AWS.Templates.Tag; use Bookstore.Books.Strings; -- function To_String begin Insert (Translations, Msg.Association (Choose_Key)); Insert (Translations, Msg.Association (Cart_Add_Key)); 250 Insert (Translations, Msg.Association (By_Key)); for I in All_Books'First .. All_Books'Last loop Books_ID := Books_ID & To_String (All_Books (I).Get_ID); 255 Books_Title := Books_Title & To_String (All_Books (I).Get_Title); Books_Price := Books_Price & Msg.To_String (All_Books (I).Get_Price); Books_First_Name := Books_First_Name 260 & To_String (All_Books (I).Get_First_Name); Books_Surname := Books_Surname & To_String (All_Books (I).Get_Surname); end loop; 265 Insert (Translations, Assoc ("BOOK_ID", Books_ID)); Insert (Translations, Assoc ("BOOK_TITLE", Books_Title)); Insert (Translations, Assoc ("BOOK_PRICE", Books_Price)); Insert (Translations, Assoc ("BOOK_FIRST_NAME", Books_First_Name)); Insert (Translations, Assoc ("BOOK_SURNAME", Books_Surname)); 270 end Get_All_Books; return AWS.Response.Build (AWS.MIME.Text_Html, String '(AWS.Templates.Parse (Page_Local_Prefix & Catalog & Ext, 275 Translations))); end Page_Catalog; ------------------ -- Page_Details -- 280 ------------------ function Page_Details (Request : in AWS.Status.Data) return AWS.Response.Data is 285 P : constant AWS.Parameters.List := AWS.Status.Parameters (Request); use AWS.Templates; -- function Assoc begin 290 if P.Exist ("bookId") then Get_Book_Data: declare Book : constant Bookstore.Books.Book 295 := Book_DAO.Get_Book (P.Get ("bookId")); use type Bookstore.Books.Value; use Bookstore.Books.Strings; -- function To_String 300 Translations : constant AWS.Templates.Translate_Table := (-- used by header.thtml Assoc ("LANG", "en"), -- book's data 305 Assoc ("BOOK_ID", To_String (Book.Get_ID)), Assoc ("BOOK_TITLE", To_String (Book.Get_Title)), Assoc ("BOOK_FIRSTNAME", To_String (Book.Get_First_Name)), Assoc ("BOOK_SURNAME", To_String (Book.Get_Surname)), Assoc ("BOOK_CALENDAR_YEAR", Integer (Book.Get_Calendar_Year)), 310 Assoc ("BOOK_DESCRIPTION", To_String (Book.Get_Description)), Assoc ("BOOK_PRICE", Msg.To_String (Book.Get_Price)), -- messages Msg.Association (By_Key), 315 Msg.Association (Critics_Key), Msg.Association (Item_Price_Key), Msg.Association (Cart_Add_Key), Msg.Association (Continue_Shopping_Key)); 320 Response : constant String := String '(AWS.Templates.Parse (Page_Local_Prefix & Details & Ext, Translations)); begin 325 return AWS.Response.Build (AWS.MIME.Text_Html, Response); end Get_Book_Data; else return AWS.Response.Build 330 (AWS.MIME.Text_Html, String '(AWS.Templates.Parse (Page_Local_Prefix & Details & Ext))); end if; end Page_Details; 335 ------------------- -- Page_Showcart -- ------------------- 340 function Page_Showcart (Request : in AWS.Status.Data) return AWS.Response.Data is Session_ID : constant AWS.Session.ID := AWS.Status.Session (Request); Translations : AWS.Templates.Translate_Set; Cart : Bookstore.Carts.Shopping_Cart 345 := Session_Cart.Get (Session_ID, "cart"); use AWS.Templates; -- procedure Insert -- function Assoc 350 begin Process_Parameters: declare P : constant AWS.Parameters.List := AWS.Status.Parameters (Request); 355 begin if P.Exist ("Clear") and then P.Get ("Clear") = "clear" then Cart.Clear; Session_Cart.Set (Session_ID, "cart", Cart); Insert (Translations, Msg.Association (Cart_Cleared_Key)); 360 end if; if P.Exist ("Remove") then declare Book : constant Bookstore.Books.Book 365 := Book_DAO.Get_Book (P.Get ("Remove")); use Bookstore.Books.Strings; -- function To_String begin Cart.Remove (Book.Get_ID); Session_Cart.Set (Session_ID, "cart", Cart); 370 Insert (Translations, Msg.Association (Cart_Removed_Key)); Insert (Translations, Assoc ("REMOVED_BOOK_TITLE", To_String (Book.Get_Title))); 375 exception when Error : Bookstore.Exceptions.Book_Not_Found_Exception => -- todo : book to remove was not found by Book_DAO Ada.Exceptions.Reraise_Occurrence (Error); end; 380 end if; end Process_Parameters; Cart_Content: declare 385 Number : constant Natural := Natural (Cart.Get_Number_Of_Items); Item_Quantity : AWS.Templates.Vector_Tag; Books_ID : AWS.Templates.Vector_Tag; Books_Title : AWS.Templates.Vector_Tag; 390 Books_Price : AWS.Templates.Vector_Tag; package Lists renames Bookstore.Cart_Items.Lists; All_Books : constant Lists.List := Cart.Get_Items; 395 procedure Process_Book (Position : Lists.Cursor) is Cart_Item : Bookstore.Cart_Items.Shopping_Cart_Item := Lists.Element (Position); use Bookstore.Books.Strings; -- function To_String begin 400 Item_Quantity := Item_Quantity & Integer (Cart_Item.Get_Quantity); Books_ID := Books_ID & To_String (Cart_Item.Get_Item.Get_ID); Books_Title := Books_Title & To_String (Cart_Item.Get_Item.Get_Title); 405 Books_Price := Books_Price & Msg.To_String (Cart_Item.Get_Item.Get_Price); end Process_Book; begin 410 Insert (Translations, Assoc ("CART_NUMBER_OF_ITEMS", Number)); Insert (Translations, Msg.Association (Cart_Contents_Key)); Insert (Translations, Msg.Association (Cart_Item_Key)); Insert (Translations, Msg.Association (Cart_Items_Key)); 415 Insert (Translations, Msg.Association (Item_Quantity_Key)); Insert (Translations, Msg.Association (Item_Title_Key)); Insert (Translations, Msg.Association (Item_Price_Key)); All_Books.Iterate (Process_Book'Access); 420 Insert (Translations, Assoc ("ITEM_QUANTITY", Item_Quantity)); Insert (Translations, Assoc ("BOOK_ID", Books_ID)); Insert (Translations, Assoc ("BOOK_TITLE", Books_Title)); Insert (Translations, Assoc ("BOOK_PRICE", Books_Price)); 425 Insert (Translations, Msg.Association (Remove_Item_Key)); Insert (Translations, Msg.Association (Subtotal_Key)); Insert (Translations, Assoc ("CART_TOTAL", Msg.To_String (Cart.Get_Total))); 430 end Cart_Content; Insert (Translations, Msg.Association (Continue_Shopping_Key)); Insert (Translations, Msg.Association (Checkout_Key)); Insert (Translations, Msg.Association (Clear_Cart_Key)); 435 Insert (Translations, Msg.Association (Cart_Empty_Key)); Insert (Translations, Msg.Association (Catalog_Key)); return AWS.Response.Build (AWS.MIME.Text_Html, 440 String '(AWS.Templates.Parse (Page_Local_Prefix & Showcart & Ext, Translations))); end Page_Showcart; 445 ------------------ -- Page_Cashier -- ------------------ 450 function Page_Cashier (Request : in AWS.Status.Data) return AWS.Response.Data is Session_ID : constant AWS.Session.ID := AWS.Status.Session (Request); 455 Cart : constant Bookstore.Carts.Shopping_Cart := Session_Cart.Get (Session_ID, "cart"); use AWS.Templates; -- function Assoc Translations : constant AWS.Templates.Translate_Table := 460 (Assoc ("LANG", "en"), Msg.Association (Amount_Key), Assoc ("CART_TOTAL", Msg.To_String (Cart.Get_Total)), Msg.Association (Purchase_Key), Msg.Association (Name_Key), 465 Msg.Association (CC_Number_Key), Msg.Association (Submit_Key)); begin return AWS.Response.Build 470 (AWS.MIME.Text_Html, String '(AWS.Templates.Parse (Page_Local_Prefix & Cashier & Ext, Translations))); end Page_Cashier; 475 ------------------ -- Page_Receipt -- ------------------ function Page_Receipt 480 (Request : in AWS.Status.Data) return AWS.Response.Data is P : constant AWS.Parameters.List := AWS.Status.Parameters (Request); use type Ada.Calendar.Time; 485 Now : Ada.Calendar.Time := Ada.Calendar.Clock + Ada.Calendar.Day_Duration'Last * 5; use AWS.Templates; -- function Assoc use GNAT.Calendar.Time_IO; -- function Image 490 -- constant ISO_Date Translations : constant AWS.Templates.Translate_Table := (Assoc ("LANG", "en"), Msg.Association (Thank_You_Key), Assoc ("CARD_NAME", P.Get ("cardname")), 495 Msg.Association (Ship_Date_Key), Assoc ("NOW", Msg.To_String (Now)), Msg.Association (Continue_Shopping_Key)); Session_ID : constant AWS.Session.ID := AWS.Status.Session (Request); 500 begin AWS.Session.Remove (Session_ID, "cart"); return AWS.Response.Build (AWS.MIME.Text_Html, 505 String '(AWS.Templates.Parse (Page_Local_Prefix & Receipt & Ext, Translations))); end Page_Receipt; ------------------- 510 -- Process_Image -- ------------------- function Process_Image (Image : in String) return AWS.Response.Data is begin 515 return AWS.Response.File (AWS.MIME.Image_Png, Image_Local_Prefix & Image); end Process_Image; ------------------ -- Image_Adains -- 520 ------------------ function Image_Adains (Request : in AWS.Status.Data) return AWS.Response.Data is begin 525 return Process_Image (Image_Adains_Name); end Image_Adains; -------------------- -- Image_Aws_Logo -- 530 -------------------- function Image_Aws_Logo (Request : in AWS.Status.Data) return AWS.Response.Data is begin 535 return Process_Image (Image_Aws_Logo_Name); end Image_Aws_Logo; ----------------------- -- Unknown_Resources -- 540 ----------------------- function Unknown_Resources (Request : in AWS.Status.Data) return AWS.Response.Data is begin 545 return AWS.Response.Acknowledge (Status_Code => AWS.Messages.S404, Message_Body => "The requested resource doesn't exist: " & AWS.Status.URI (Request), Content_Type => AWS.MIME.Text_Plain); 550 end Unknown_Resources; end Bookstore_2.Requests_Processing;