Architecture
The framework’s implementation relies on very well documented patterns and strategies such as Front Controller, Logical Resource Mapping, Context Object, Application Controller, Command Handler, Transform Handler, Command, Adapter, DAO and others.

Front Controller
Controller components are most importance part of the framework. Almost all controller classes are provided by the framework. The only controller classes that developer needs to write are the commands. A user defined command object is extended from Command class and implements Command pattern. The commands are managed by Application Controller (AppController class).
In command pattern a generic interface is used for custom objects that service the request. This keeps the objects independent of each other providing an easy and flexible way for developer to extend the systems functionality.
The command objects serve as bridge between the Controller and the Model code layers. Ideally, no business logic should be coded inside execute() method of the Command; it should be delegated to the business domain objects. In simple case, it is okay to leave it right in the Command object for convenience.
FrontController is the central access point for the requests to the framework. There are 4 main activities which FrontController performs:
- Logical resource mapping
- Creating RequestContext
- Processing the RequestContext
- Dispatching ResponseContext to the View
Logical resource mapping
By default, TROIKA.ASP framework uses a special HTTP variable cmd to retrieve a command name. We call this action parameter. You can easily change this it any other name by altering a constant in FrontController class:
FrontController.ACTION_NAME = "cmd";
A simple GET request might look like this:
http://your.server.com/troika.asp?cmd=command1¶m1=value1¶m2=value2.
The framework looks for action parameter in various ASP repositories in the following order:
- Request.QueryString
- Request.From
- Session
If it cannot find the variable or the value of it is empty an Error is thrown:
Sometimes, the URL with the action parameter and other optional parameters might be too long winded or undesirable for other reasons. There are a number of strategies to make it shorter. For instance you create an ASP page command1.asp containing the following implementation:
<script language="JavaScript" runat="server">
Session.Contents("cmd") = "command1";
Session.Contents("param1") = "value1";
Session.Contents("param2") = "value2";
Server.Execute("/troika.asp");
Session.Contents.Remove("cmd");
Session.Contents.Remove("param1");
Session.Contents.Remove("param2");
</script>
In the case, the URL might look like this:
http://your.server.com/command1.asp
Another strategy would be to create a custom 404.asp page. Configure IIS server to forward all “Page Not Found” errors to it. Inside of the page you could check internal map to see if a particular URI matches a certain Command object and do the trick we did with command1.asp, otherwise return HTTP status 404 as usual.
Creating RequestContext
This is important function of the framework. The FrontController creates RequestContext translating ASP specific context to protocol independent object. This decouples request handling code layer from ASP specific code. This makes it easier to test the request handling code.

Once FrontController extracted the name of the Command from the action parameter it uses a Config class to lookup a CommandMap object.
If there in no mapping to be found an error is thrown:
The CommandMap object has an indirect handle to RequestContext object as a string (name property). Here is xml fragment from config.xml - the main configuration file. It is parsed and loaded by Config class.
ASM/MVC framework configuration file is config.xml:
...
<req-ctx-maps>
<req-ctx-map name="pageForm" type="PageForm" />
<req-ctx-map name="loginForm" type="LoginForm" />
<req-ctx-map name="changePassForm" type="ChangePassForm" />
<req-ctx-map name="messageForm" type="MessageForm" />
</req-ctx-maps>
...
<cmd-map action="changepass" validate="true">
<name>changePassForm</name>
<type>ChangePassAction</type>
<input redirect="false" path="/views/changepass_err.xsl" />
<forwards>
<forward name="message" redirect="false"
path="/views/changepass_message.xsl" />
<forward name="success" redirect="false"
path="/views/changepass_go.xsl" />
</forwards>
</cmd-map>
…

The name tag is optional. If it is not defined, FrontController will create and empty RequestContext.
Once the name of the RequestContext mapping is known FrontController looks up the class name from RequestContextMap (see req-ctx-maps tag). It then creates a new instance of RequestContext and fills all the fields with the data from ASP request object.
Processing the RequestContext
Once the RequestContext is created and initialised the request is passed on to Application Controller component for handling.

The Application Controller (AppController) is responsible for command management. That includes locating and executing a specific command which will service the request and return the ResponseContext back to the FrontController for view management.

Dispatching ResponseContext to the View
If the Application Controller returns ResponseContext FrontContoller passes it to Dispatcher class for further processing. The ResponseContext class contains reference to Forward class which is indirect handle to the View’s stylesheet. Also ResponseContext class stores Error objects if any and Model objects in a Map. The Model Map is populated by Command objects and it contains the command’s specific results to be transformed by XSL stylesheet processor into HTML.
Here are sample declarations of Forward from CommandMap:
<forward name="action-error" redirect="true" path="/views/error.html" />
<forward name="success" redirect="false" path="/views/hello.xsl" />
While the first one redirects the browser to URI
/views/error.html
the second instructs the framework to transform the output XML into HTML using hello.xsl stylesheet before returning it to the browser. It gets XML data concatenating XML string from RequestContext, ResponseContext and some data from Session objects.
The FrontController obtains all view related objected to be used with XSLT transformation engine. This is TransformerHandler pattern.
Depending on how the Forward instance is configured the Dispatcher class will either redirect or will render the HTML using Forward path attribute to locate the stylesheet.
In debug mode (
Application.Contents("debug") = 1;
see in global.asa) the Dispatcher also appends the resulting XML as commented out string at the bottom of each HTML page.
