Answered step by step
Verified Expert Solution
Question
1 Approved Answer
Create a Command-line UI for Searching and Displaying Page Info Separation of UI and Search operations We can imagine that there may be many different
Create a Command-line UI for Searching and Displaying Page Info Separation of UI and Search operations We can imagine that there may be many different interfaces to the primary web search engine. We could have a web-based interface, a stand- alone GUI application, or (as we will have for this project) a terminal-based, text interface. Because we should NOT couple the search abilities and the UI for accessing it, we will split these into different classes. You will implement a Searchui and SearchEng class. The SearchuI provides a text interface that allows user to enter commands to search for and retreive webpage information and a SearchEng class that implements these basic operations regardless of the interface. Search UI and Commands In searchui.h/cpp, we will implement the main user interface logic which will use the terminal and perform text-based queries via some form of std::istream/std::ostream. The Searchur class is complete but makes references to other classes in the cmdhandler.h/cpp and searcheng.h/cpp files that you will need to write. You may assume all commands will be on a single line and NOT span multiple lines. We have defined an enumeration that will be used to return status from command handling. HANDLER_OK: The command was able to complete and processing should continue. HANDLER_ERROR: An error occurred but processing should continue. HANDLER_QUIT: The QUIT command was entered and the program should exit. Menu of Commands QUIT should quit the program by returning HANDLER_QUIT. AND word1 word2 ... wordN: the user wants to see all the pages that contain ALL of the given words. The number of words here can be arbitrary. There will always be at least one whitespace between each element (AND and any of the search term(s)). If no terms are provide, just return an empty set. If only one term is provided, return all the pages containing that term. No errors may occur for an AND command. OR word1 word2 ... WordN: the user wants to see all the pages that contain ANY (at least one) of the given words. The number of words here can be arbitrary. If no terms are provide, just return an empty set. If only one term is provided, return all the pages containing that term. No errors may occur for an OR command. DIFF word1 word2 ... wordN: the user wants to see all the pages that contain word1 but do NOT contain ANY of the following words (i.e. find the pages that have word1 and then remove any of those pages that also contain word2, then remove any of the remaining pages that contain word3, etc.) The number of words here can be arbitrary. If no terms are provide, just return an empty set. If only one term is provided, return all the pages containing that term. No errors may occur for a DIFF command. PRINT page : displays a webpage using the display format described below (ie. with links removed). Return HANDLER_ERROR if the page does not exist. You may need to catch an exception from the search engine and then return the HANDLER_ERROR INCOMING page : displays the number of incoming links for the specified page and then lists those page names (1 per line) that have a link to page. Return HANDLER_ERROR if the page does not exist OUTGOING page : displays the number of outgoing links for the specified page and then lists those page names. Return HANDLER_ERROR if the page does not exist. Queries should be case-insensitive, so if the user typed "UsC", and a page contained "USC", that page should be a match. In response to the query, you should tell the user how many pages matched his/her query, and if it was more than 0, display all the page filenames. We have provided this logic to you in a display_hits(...) function in util.h/cpp. You MUST use it for display results of AND, OR, DIFF queries. For commands that require a page name, you may assume the page/file name entered is case-sensitive and you do not have to worry about converting the cases. Examples of each command are provided in the test-small folder under search. There is a sample index file and pages. By running the input of query1.txt you should get the output in query1.exp. The same is true for query2.txt and query2.exp. Please study these carefully to ensure you understand what each command should do. Command Processing and Polymorphism To process commands from the user, we will use a polymorphic approach to try to make each command and its processing loosely coupled from others AND to allow for easy addition of NEW commands/capabilities in the future that do not require modification of existing code. Rather than writing a large if..else if..else if style statement to check commands, we have provided you a base class Handler in handler.h and handler.cpp . This class defines a handle function which will invoke virtual helper functions (that are protected) to see if the derived class a.) can process this kind of command and if it can, b.) actually process (carry-out) the desired command. This approach uses a common design pattern for object-oriented programming called "chain of responibility". A great website to read more about this and other design patterns is sourcemaking.com. We have already written two derived classes to process the QUIT command and PRINT command in cmdhandler.h and cmdhandler.cpp. Use that as a guide for writing classes for the AND, OR, DIFF, INCOMING , and OUTGOING commands. You can put all the classes in the same file (cmdhandler.h and cmdhandler.cpp ). If you look at the handle() function you will see its signature is: HANDLER_STATUS_T handle(SearchEng* eng, const std::string& cmd, std::istream& instr, std::ostream& ostr); We will pass in the search engine so you have access to all of its public functionality, cmd is the identifier of the command (i.e. QUIT, PRINT, AND, OR , etc.), and instr and ostr are the the input and output streams from which you can read in the remaining, expected arguments for the specific command (e.g. search terms, etc.) and output the results in this way, we can read and print result to files or to cin/cout ). We included this design approach so you can see how it can make processing cleaner. If you look at Searchul::run you'll notice the loop to process commands is very simple and straightforward. In addition, we achieve more loose coupling because now we can add support for new commands by simply writing a new derived Handler class and instantiating it and adding it to the chain in the Searchul. Nothing in Searchul::runo would need to change. In maino, you will need to create these derived command handler objects and register them with the Searchus object before calling SearchUI::run(). You MUST use this command handler approach rather than simple if statements for checking command inputs. Spend some time to understand how this chain-of-responsibility design works by reading and studying the code a few time and referring to the given website. Consider its benefits. If you have any questions, please talk to your instructor or TA. You will need to complete the rest of cmd_handlers.cpp to implement the commands just described. Create a Command-line UI for Searching and Displaying Page Info Separation of UI and Search operations We can imagine that there may be many different interfaces to the primary web search engine. We could have a web-based interface, a stand- alone GUI application, or (as we will have for this project) a terminal-based, text interface. Because we should NOT couple the search abilities and the UI for accessing it, we will split these into different classes. You will implement a Searchui and SearchEng class. The SearchuI provides a text interface that allows user to enter commands to search for and retreive webpage information and a SearchEng class that implements these basic operations regardless of the interface. Search UI and Commands In searchui.h/cpp, we will implement the main user interface logic which will use the terminal and perform text-based queries via some form of std::istream/std::ostream. The Searchur class is complete but makes references to other classes in the cmdhandler.h/cpp and searcheng.h/cpp files that you will need to write. You may assume all commands will be on a single line and NOT span multiple lines. We have defined an enumeration that will be used to return status from command handling. HANDLER_OK: The command was able to complete and processing should continue. HANDLER_ERROR: An error occurred but processing should continue. HANDLER_QUIT: The QUIT command was entered and the program should exit. Menu of Commands QUIT should quit the program by returning HANDLER_QUIT. AND word1 word2 ... wordN: the user wants to see all the pages that contain ALL of the given words. The number of words here can be arbitrary. There will always be at least one whitespace between each element (AND and any of the search term(s)). If no terms are provide, just return an empty set. If only one term is provided, return all the pages containing that term. No errors may occur for an AND command. OR word1 word2 ... WordN: the user wants to see all the pages that contain ANY (at least one) of the given words. The number of words here can be arbitrary. If no terms are provide, just return an empty set. If only one term is provided, return all the pages containing that term. No errors may occur for an OR command. DIFF word1 word2 ... wordN: the user wants to see all the pages that contain word1 but do NOT contain ANY of the following words (i.e. find the pages that have word1 and then remove any of those pages that also contain word2, then remove any of the remaining pages that contain word3, etc.) The number of words here can be arbitrary. If no terms are provide, just return an empty set. If only one term is provided, return all the pages containing that term. No errors may occur for a DIFF command. PRINT page : displays a webpage using the display format described below (ie. with links removed). Return HANDLER_ERROR if the page does not exist. You may need to catch an exception from the search engine and then return the HANDLER_ERROR INCOMING page : displays the number of incoming links for the specified page and then lists those page names (1 per line) that have a link to page. Return HANDLER_ERROR if the page does not exist OUTGOING page : displays the number of outgoing links for the specified page and then lists those page names. Return HANDLER_ERROR if the page does not exist. Queries should be case-insensitive, so if the user typed "UsC", and a page contained "USC", that page should be a match. In response to the query, you should tell the user how many pages matched his/her query, and if it was more than 0, display all the page filenames. We have provided this logic to you in a display_hits(...) function in util.h/cpp. You MUST use it for display results of AND, OR, DIFF queries. For commands that require a page name, you may assume the page/file name entered is case-sensitive and you do not have to worry about converting the cases. Examples of each command are provided in the test-small folder under search. There is a sample index file and pages. By running the input of query1.txt you should get the output in query1.exp. The same is true for query2.txt and query2.exp. Please study these carefully to ensure you understand what each command should do. Command Processing and Polymorphism To process commands from the user, we will use a polymorphic approach to try to make each command and its processing loosely coupled from others AND to allow for easy addition of NEW commands/capabilities in the future that do not require modification of existing code. Rather than writing a large if..else if..else if style statement to check commands, we have provided you a base class Handler in handler.h and handler.cpp . This class defines a handle function which will invoke virtual helper functions (that are protected) to see if the derived class a.) can process this kind of command and if it can, b.) actually process (carry-out) the desired command. This approach uses a common design pattern for object-oriented programming called "chain of responibility". A great website to read more about this and other design patterns is sourcemaking.com. We have already written two derived classes to process the QUIT command and PRINT command in cmdhandler.h and cmdhandler.cpp. Use that as a guide for writing classes for the AND, OR, DIFF, INCOMING , and OUTGOING commands. You can put all the classes in the same file (cmdhandler.h and cmdhandler.cpp ). If you look at the handle() function you will see its signature is: HANDLER_STATUS_T handle(SearchEng* eng, const std::string& cmd, std::istream& instr, std::ostream& ostr); We will pass in the search engine so you have access to all of its public functionality, cmd is the identifier of the command (i.e. QUIT, PRINT, AND, OR , etc.), and instr and ostr are the the input and output streams from which you can read in the remaining, expected arguments for the specific command (e.g. search terms, etc.) and output the results in this way, we can read and print result to files or to cin/cout ). We included this design approach so you can see how it can make processing cleaner. If you look at Searchul::run you'll notice the loop to process commands is very simple and straightforward. In addition, we achieve more loose coupling because now we can add support for new commands by simply writing a new derived Handler class and instantiating it and adding it to the chain in the Searchul. Nothing in Searchul::runo would need to change. In maino, you will need to create these derived command handler objects and register them with the Searchus object before calling SearchUI::run(). You MUST use this command handler approach rather than simple if statements for checking command inputs. Spend some time to understand how this chain-of-responsibility design works by reading and studying the code a few time and referring to the given website. Consider its benefits. If you have any questions, please talk to your instructor or TA. You will need to complete the rest of cmd_handlers.cpp to implement the commands just described
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started