From: Chris W. <la...@us...> - 2005-02-26 05:06:43
|
Update of /cvsroot/openinteract/OpenInteract2/doc/Manual In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18028 Modified Files: Architecture.pod Log Message: add references to action resolvers; other small fixes Index: Architecture.pod =================================================================== RCS file: /cvsroot/openinteract/OpenInteract2/doc/Manual/Architecture.pod,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Architecture.pod 25 Feb 2005 05:42:06 -0000 1.11 --- Architecture.pod 26 Feb 2005 05:06:33 -0000 1.12 *************** *** 19,26 **** MVC was developed in Smalltalk and targeted at desktop applications. It's meant to decouple the various graphical widgets ! from the actions resulting from them. While some (see link to Andy ! Wardley's discussion in L<SEE ALSO>) have argued that MVC isn't ! appropriate for web applications, it's still useful to categorize how ! the different pieces of the application are separated. =head2 Model --- 19,26 ---- MVC was developed in Smalltalk and targeted at desktop applications. It's meant to decouple the various graphical widgets ! from the actions resulting from them. While some have argued that MVC ! isn't appropriate for web applications (see link to Andy Wardley's ! discussion in L<SEE ALSO>), it's still useful to categorize how the ! different pieces of the application are separated. =head2 Model *************** *** 79,89 **** =head2 Controller ! Also known as a dispatcher, this is what decides which model (Action) ! is called and how to represent the data from the outside world. These ! are represented by the Controller object which dispatches the user's ! request, the Request object which takes the user's inputs (however ! they arrive) and translates them to a standard format, and the ! Response object which translates the work done during the request ! cycle into something the user can understand. For a web application: --- 79,89 ---- =head2 Controller ! Also known as a dispatcher, this uses a utility (ActionResolver) to ! decide which model (Action) is called and how to represent the data ! from the outside world. These are represented by the Controller object ! which dispatches the user's request, the Request object which takes ! the user's inputs (however they arrive) and translates them to a ! standard format, and the Response object which translates the work ! done during the request cycle into something the user can understand. For a web application: *************** *** 99,108 **** =item * ! The Controller instantiates the Action matching the URL as reported by ! the Request, populates the Action with any necessary information and ! executes the Action, capturing its output. It doesn't care what the ! Action does or how the Action does it. The Controller will also place ! this Action's output in a larger context (e.g., as part of a larger ! web page) as necessary. =item * --- 99,109 ---- =item * ! The Controller hands the URL off to the ActionResolver, which ! instantiates a number of small objects in a chain of ! responsibility. It then asks each if it's able to create an action ! from the given URL. Once created the Controller executes the Action, ! capturing its output. It doesn't care what the Action does or how the ! Action does it. The Controller will also place this Action's output in ! a larger context (e.g., as part of a larger web page) as necessary. =item * *************** *** 117,129 **** =head2 Overview ! The Context (abbrev: CTX) glues the system together and is therefore ! used everywhere. It holds all application configuration information ! and provides a central lookup mechanism for actions, content ! generators, controllers and SPOPS object classes. ! It is a singleton (there's only one in the system at any time) and ! this singleton can be imported from the ! L<OpenInteract2::Context|OpenInteract2::Context> class since it's used ! fairly often. =head2 Creating the Context --- 118,129 ---- =head2 Overview ! The Context (abbrev: CTX) glues the system together so you'll see it a ! lot.It holds all application configuration information and provides a ! central lookup mechanism for actions, content generators, controllers ! and SPOPS object classes. ! It is a singleton (there's only one in the system at any time) and you ! can import this singleton reference from the ! L<OpenInteract2::Context|OpenInteract2::Context> class. =head2 Creating the Context *************** *** 134,138 **** when bootstrapping a new website into existence, and this is already done for you in ! L<OpenInteract2::Manage::Website::Create|OpenInteract2::Manage::Website::Create>. So normally it looks something like this: --- 134,138 ---- when bootstrapping a new website into existence, and this is already done for you in ! L<OpenInteract2::Manage::Website::Create|OpenInteract2::Manage::Website::Create>.) So normally it looks something like this: *************** *** 142,147 **** }); ! Once it's created the C<CTX> symbol can be imported and used anywhere, ! like this: use OpenInteract2::Context qw( CTX ); --- 142,147 ---- }); ! Once it's created the C<CTX> symbol from L<OpenInteract2::Context> can ! be imported and used anywhere, like this: use OpenInteract2::Context qw( CTX ); *************** *** 177,183 **** Creating an adapter is not difficult. Adapter classes tend to be fairly short as most of the work is done in in the ! L<OpenInteract2::Request|OpenInteract2::Request>/L<OpenInteract2::Response|OpenInteract2::Response> ! subclasses. For instance, here's the full adapter for Apache/mod_perl ! 1.x: package Apache::OpenInteract2; --- 177,183 ---- Creating an adapter is not difficult. Adapter classes tend to be fairly short as most of the work is done in in the ! L<OpenInteract2::Request|OpenInteract2::Request> and ! L<OpenInteract2::Response|OpenInteract2::Response> subclasses. For ! instance, here's the full adapter for Apache/mod_perl 1.x: package Apache::OpenInteract2; *************** *** 241,246 **** # Create the context... ! my $ctx = OpenInteract2::Context->create( ! $base_config, { temp_lib_create => 'create' } ); # ...let the context know what type of adapter we are --- 241,245 ---- # Create the context... ! my $ctx = OpenInteract2::Context->create( $base_config ); # ...let the context know what type of adapter we are *************** *** 316,322 **** =back ! Additionally if your adapter is more of a standalone service (like the ! C<oi2_daemon>) that spawns off children/threads for requests, you need ! to also be aware of the following: =over 4 --- 315,321 ---- =back ! If your adapter is more of a standalone service (like the ! C<oi2_daemon>) that spawns off children/threads for requests, you also ! need to also be aware of the following: =over 4 *************** *** 346,356 **** processing to the L<OpenInteract2::Controller|OpenInteract2::Controller> object. Now ! we're entirely inside the OI2 server environment. This reads the ! action and task from the request and creates the relevant action ! object that will generate the content. It knows which action object to ! create through a URL-to-action mapping created at Context startup. The ! most-used controller (L<OpenInteract2::Controller::MainTemplate|OpenInteract2::Controller::MainTemplate>) ! places the generated content in a larger scope so you can control common graphical elements (sidebars, menus, etc.) from once place. Another controller --- 345,394 ---- processing to the L<OpenInteract2::Controller|OpenInteract2::Controller> object. Now ! we're entirely inside the OI2 server environment. Its main ! responsibility is to match up the URL with an L<OpenInteract2::Action> ! object and execute it, returning its generate content to the browser. ! ! To match up the URL with the Action we use a chain of responsibility ! pattern, organized by L<OpenInteract2::ActionResolver>. Children ! classes under this namespace are C<require>d at server startup. So for ! each request the main ActionResolver class will instantiate all its ! children and pass each the L<OpenInteract2::Request> object and ! URL. Each child can decide to match up the URL with an ! L<OpenInteract2::Action> object or do nothing. ! ! The ActionResolvers shipped with the system can respond to: ! ! =over 4 ! ! =item B<user directory requests> ! ! So something like C<http://foo.com/~lucyliu/> will get recognized by ! this resolver and matched to a user action. A successive item in the ! URL (e.g., '/~lucyliu/profile/') will get assigned as the action's ! task. ! ! =item B<name from URL> ! ! This will get used most often -- from something like ! C<http://foo.com/news/latest/> it finds the name ('news') and tries to ! lookup an action based on it. If found it also assigns the next item ! in the URL as the action's task. ! ! =item B<action not found or action missing> ! ! If the name in the URL wasn't matched to a URL we assign it to the ! 'not found' action. This is a catch-all action and very useful if you ! want to map what look like simple page requests to an ! L<OpenInteract2::Action> object. By default we use the 'page' action. ! ! And if there was no action in the URL (e.g., C<http://foo.com/>) we ! invoke the 'none' action. This also uses the 'page' action. ! ! =back ! ! Once the action's found we call C<execute()> on it, which generates ! its content. The most-used controller (L<OpenInteract2::Controller::MainTemplate|OpenInteract2::Controller::MainTemplate>) ! places that generated content in a larger scope so you can control common graphical elements (sidebars, menus, etc.) from once place. Another controller *************** *** 364,369 **** Actions are the core of OpenInteract2. Each action provides a discrete set of functionality. What "discrete set" means is up to the ! developer, but typically this is a set of SCRUD (Search - CReate - ! Update - Delete) operations on a class of objects. Each action is represented by zero or more URLs, and each operation is --- 402,407 ---- Actions are the core of OpenInteract2. Each action provides a discrete set of functionality. What "discrete set" means is up to the ! developer, but typically this is a set of CRUDS (CReate - Update - ! Delete - Search) operations on a class of objects. Each action is represented by zero or more URLs, and each operation is *************** *** 371,374 **** --- 409,417 ---- action my URLs might look like: + http://foo.com/news/ + http://foo.com/news/display/ + http://foo.com/news/search_form/ + http://foo.com/news/search/ + Every task returns some sort of content, generally by passing data to a Content Generator which marries it with a template. See *************** *** 462,482 **** request and response objects created earlier. ! The controller asks the request for the action name and asks the ! context for an action object of that name. (It's always a subclass of ! L<OpenInteract2::Action|OpenInteract2::Action>.) If the action name ! exists but is not found we use the action named in the ! C<action_info.not_found> server configuration key. If the action name ! doesn't exist we use the action from C<action_info.none>. ! ! Once the action is found we assign it the task (if available) as ! reported by the request. =head2 Step 5: Adapter Executes Controller ! If created properly the adapter calls C<execute()> on the ! controller. This starts the content generation process running. ! The controller will call C<execute()> on the action which returns the ! content for it. =head2 Step 6: Action Finds Task --- 505,522 ---- request and response objects created earlier. ! The controller invokes a chain of responsibility provided by ! L<OpenInteract2::ActionResolver> to figure out what action to create ! based on the URL. =head2 Step 5: Adapter Executes Controller ! If the controller was created properly the adapter calls C<execute()> ! on it. This starts the content generation process running. ! The controller will call C<execute()> on the action which starts the ! action's content generation process. ! ! If the controller was not created properly it threw an exception which ! we return as content. =head2 Step 6: Action Finds Task |