paulb@654 | 1 | <?xml version="1.0" encoding="iso-8859-1"?> |
paulb@601 | 2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
paulb@601 | 3 | <html xmlns="http://www.w3.org/1999/xhtml"><head><meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" /> |
paulb@654 | 4 | <title>Selectors - Components for Dispatching to Resources</title> |
paulb@601 | 5 | <link href="styles.css" rel="stylesheet" type="text/css" /></head> |
paulb@601 | 6 | <body> |
paulb@601 | 7 | <h1>Selectors - Components for Dispatching to Resources</h1> |
paulb@749 | 8 | |
paulb@749 | 9 | <p>The <code>Selectors</code> module provides classes (although currently only |
paulb@749 | 10 | one class is supplied) which act as standard WebStack resources, but which |
paulb@749 | 11 | attempt to "select" other resources, dispatch each request to those resources, |
paulb@749 | 12 | and to cause various side-effects, mostly on the attributes stored on the |
paulb@749 | 13 | transaction object. These "selector" classes behave those in the |
paulb@749 | 14 | <code>ResourceMap</code> module, but aspire to be more generally |
paulb@749 | 15 | applicable.</p> |
paulb@749 | 16 | |
paulb@749 | 17 | <h2>Selecting Path Roots with PathSelector</h2> |
paulb@749 | 18 | |
paulb@749 | 19 | <p>In non-trivial applications, it is often desirable to know the path or URL |
paulb@749 | 20 | to a particular resource, especially the "root" resource under which the |
paulb@749 | 21 | application or one of its components may reside. The <code>PathSelector</code> |
paulb@749 | 22 | class can be instantiated and be made to refer to a resource, recording such |
paulb@749 | 23 | path or URL details in an attribute for later inspection.</p> |
paulb@749 | 24 | |
paulb@749 | 25 | <div class="WebStack"> |
paulb@749 | 26 | <h3>WebStack API - The PathSelector Class</h3> |
paulb@749 | 27 | |
paulb@749 | 28 | <p>The <code>PathSelector</code> class (found in the |
paulb@749 | 29 | <code>WebStack.Resources.Selectors</code> module) wraps resource objects whose |
paulb@749 | 30 | location (as indicated by a path or URL) should be recorded as an attribute on |
paulb@749 | 31 | the current transaction. The most common use of the class is to record the |
paulb@749 | 32 | "root" resource's location, and this would be done as follows:</p> |
paulb@749 | 33 | |
paulb@749 | 34 | <pre> |
paulb@749 | 35 | def get_site_map(): |
paulb@749 | 36 | return PathSelector(MyResource()) |
paulb@749 | 37 | </pre> |
paulb@749 | 38 | |
paulb@749 | 39 | <p>Here, the <code>get_site_map</code> function (as described in the <a |
paulb@749 | 40 | href="deploying.html">"Deploying a WebStack Application"</a> document) would |
paulb@749 | 41 | provide a <code>PathSelector</code> object instead of an instance of the |
paulb@749 | 42 | <code>MyResource</code> class. However, the side-effect of combining these two |
paulb@749 | 43 | resources would be the availability of an attribute named <code>root</code> on |
paulb@749 | 44 | the transaction object. Thus, the "root" <code>MyResource</code> object and, |
paulb@749 | 45 | indeed, all resource objects visited after this side-effect has occurred will |
paulb@749 | 46 | have access to the "root" path or URL information.</p> |
paulb@749 | 47 | |
paulb@749 | 48 | <h4>Further Reading</h4> |
paulb@749 | 49 | |
paulb@749 | 50 | <p>The <a |
paulb@749 | 51 | href="../apidocs/public/WebStack.Resources.Selectors.PathSelector-class.html">API |
paulb@749 | 52 | documentation</a> for the <code>PathSelector</code> class provides additional |
paulb@749 | 53 | information.</p> |
paulb@749 | 54 | |
paulb@749 | 55 | </div> |
paulb@749 | 56 | |
paulb@749 | 57 | <h2>Defining Encodings using EncodingSelector</h2> |
paulb@749 | 58 | |
paulb@749 | 59 | <p>One frequently bothersome aspect of writing Web applications involves the |
paulb@749 | 60 | processing and production of text in different encodings. Whilst the WebStack |
paulb@749 | 61 | API lets applications explicitly state the character encoding for various |
paulb@749 | 62 | operations, one often wants to be able to ignore such details since they start |
paulb@749 | 63 | to clutter up application code. The <code>EncodingSelector</code> class offers |
paulb@749 | 64 | a basic solution which is compatible with the mechanisms in transaction |
paulb@749 | 65 | objects: by wrapping WebStack resources with instances of |
paulb@749 | 66 | <code>EncodingSelector</code>, an application-wide default encoding (or |
paulb@749 | 67 | character set) will be defined; this will result in request information being |
paulb@749 | 68 | processed according to the stated encoding and response information being |
paulb@749 | 69 | produced according to that encoding (see below for more details of the latter |
paulb@749 | 70 | activity).</p> |
paulb@749 | 71 | |
paulb@749 | 72 | <div class="WebStack"> |
paulb@749 | 73 | <h3>WebStack API - The EncodingSelector Class</h3> |
paulb@749 | 74 | |
paulb@749 | 75 | <p>The <code>EncodingSelector</code> class (found in the |
paulb@749 | 76 | <code>WebStack.Resources.Selectors</code> module) wraps resource |
paulb@749 | 77 | objects whilst changing the default encoding of the current transaction |
paulb@749 | 78 | object. The class can be applied like this:</p> |
paulb@749 | 79 | |
paulb@749 | 80 | <pre> |
paulb@749 | 81 | def get_site_map(): |
paulb@749 | 82 | return EncodingSelector(MyResource(), "utf-8") |
paulb@749 | 83 | </pre> |
paulb@749 | 84 | |
paulb@749 | 85 | <p>Here, the <code>get_site_map</code> function (as described in the <a |
paulb@749 | 86 | href="deploying.html">"Deploying a WebStack Application"</a> document) would |
paulb@749 | 87 | provide a <code>EncodingSelector</code> object instead of an instance of the |
paulb@749 | 88 | <code>MyResource</code> class. However, the <code>EncodingSelector</code> will |
paulb@749 | 89 | forward requests on to <code>MyResource</code> (since it "selects" that |
paulb@749 | 90 | resource), whilst setting the default encoding to be <code>"utf-8"</code>.</p> |
paulb@749 | 91 | |
paulb@749 | 92 | <h4>Request Streams and Encodings</h4> |
paulb@749 | 93 | |
paulb@749 | 94 | <p>Although a default encoding affects the processing of request parameters, |
paulb@749 | 95 | direct access to the request stream using the <code>get_request_stream</code> |
paulb@749 | 96 | method will only produce plain strings. This behaviour is justified by the |
paulb@749 | 97 | observation that, if conversion from an encoding to Unicode were to take place, |
paulb@749 | 98 | the resulting character values may be unsuitable substitutes for the original |
paulb@749 | 99 | byte values in applications intending to make use of the raw incoming (possibly |
paulb@749 | 100 | binary) data. A recipe for making a Unicode stream is provided in the <a |
paulb@749 | 101 | href="encodings.html">"Character Encodings"</a> document.</p> |
paulb@749 | 102 | |
paulb@749 | 103 | <h4>Response Encodings and Content Types</h4> |
paulb@749 | 104 | |
paulb@749 | 105 | <p>Although <code>EncodingSelector</code> sets a default encoding, responses |
paulb@749 | 106 | will generally be written in that encoding, at least if textual data is written |
paulb@749 | 107 | to the response stream as Unicode objects. However, the content type must |
paulb@749 | 108 | typically be set either to match the encoding in use or to not specify an |
paulb@749 | 109 | encoding. It may become necessary to find out what the response stream encoding |
paulb@749 | 110 | is when creating a <code>ContentType</code> object. For this and other |
paulb@749 | 111 | purposes, the <code>get_response_stream_encoding</code> method is available on |
paulb@749 | 112 | the transaction object<code></code>:</p> |
paulb@601 | 113 | |
paulb@749 | 114 | <pre> |
paulb@749 | 115 | from WebStack.Generic import ContentType |
paulb@749 | 116 | |
paulb@749 | 117 | def respond(self, trans): |
paulb@749 | 118 | |
paulb@749 | 119 | # Some code... |
paulb@749 | 120 | |
paulb@749 | 121 | trans.set_content_type(ContentType("text/html", trans.get_response_stream_encoding())) |
paulb@749 | 122 | out = trans.get_response_stream() |
paulb@749 | 123 | out.write(some_unicode_object) |
paulb@749 | 124 | </pre> |
paulb@749 | 125 | |
paulb@749 | 126 | <p>However, it is completely acceptable to omit the encoding information where |
paulb@749 | 127 | a default encoding has been set:</p> |
paulb@749 | 128 | |
paulb@749 | 129 | <pre> |
paulb@749 | 130 | trans.set_content_type(ContentType("text/html")) # no encoding/charset specified |
paulb@749 | 131 | </pre> |
paulb@749 | 132 | |
paulb@749 | 133 | <h4>Reading the Default Directly</h4> |
paulb@749 | 134 | |
paulb@749 | 135 | <p>For some activities, such as making a Unicode stream from the request |
paulb@749 | 136 | stream, it is desirable to find out the encoding set by the selector. This |
paulb@749 | 137 | information is made available on transaction objects as the |
paulb@749 | 138 | <code>default_charset</code> attribute.</p> |
paulb@749 | 139 | |
paulb@749 | 140 | <h4>Further Reading</h4> |
paulb@749 | 141 | |
paulb@749 | 142 | <p>The <a |
paulb@749 | 143 | href="../apidocs/public/WebStack.Resources.Selectors.EncodingSelector-class.html">API |
paulb@749 | 144 | documentation</a> for the <code>EncodingSelector</code> class provides |
paulb@749 | 145 | additional information, along with the <a href="responses.html">"Responses and |
paulb@749 | 146 | Presentation"</a> document.</p> |
paulb@749 | 147 | |
paulb@749 | 148 | </div> |
paulb@749 | 149 | |
paulb@749 | 150 | <h2>Managing Database Resources</h2> |
paulb@749 | 151 | |
paulb@749 | 152 | <p>Web applications must often employ external resources such as database |
paulb@749 | 153 | systems, leading developers to consider effective mechanisms to manage such |
paulb@749 | 154 | resources. Although an application can initially open a database connection |
paulb@749 | 155 | and make it available to resources, it is essential that such resources access |
paulb@749 | 156 | the connection in a way that does not cause problems over time. The |
paulb@749 | 157 | <code>StoreSelector</code> class offers an elementary solution for resources |
paulb@749 | 158 | employing database connections by storing a connection object in an attribute |
paulb@749 | 159 | on the transaction object, such that resources may obtain the connection |
paulb@749 | 160 | merely by accessing the appropriate attribute. Moreover, the |
paulb@749 | 161 | <code>StoreSelector</code> also ensures that database transactions are |
paulb@749 | 162 | terminated in a timely fashion by calling the <code>rollback</code> method on |
paulb@749 | 163 | the connection when a resource (or potentially many resources) have completed |
paulb@749 | 164 | their work.</p> |
paulb@629 | 165 | |
paulb@749 | 166 | <div class="WebStack"> |
paulb@749 | 167 | <h3>WebStack API - The StoreSelector Class</h3> |
paulb@749 | 168 | |
paulb@749 | 169 | <p>The <code>StoreSelector</code> class (found in the |
paulb@749 | 170 | <code>WebStack.Resources.Selectors</code> module) wraps resource |
paulb@749 | 171 | objects whilst maintaining a reference to a database connection or store |
paulb@749 | 172 | object as an attribute on a WebStack transaction object. The class can be |
paulb@749 | 173 | applied like this:</p> |
paulb@749 | 174 | |
paulb@749 | 175 | <pre> |
paulb@749 | 176 | def get_site_map(connection): |
paulb@749 | 177 | return StoreSelector(MyResource(), connection) |
paulb@749 | 178 | </pre> |
paulb@749 | 179 | |
paulb@749 | 180 | <p>Here, the <code>get_site_map</code> function (as described in the <a |
paulb@749 | 181 | href="deploying.html">"Deploying a WebStack Application"</a> document) would |
paulb@749 | 182 | provide a <code>StoreSelector</code> object instead of an instance of the |
paulb@749 | 183 | <code>MyResource</code> class. However, the <code>StoreSelector</code> will |
paulb@749 | 184 | forward requests on to <code>MyResource</code> (since it "selects" that |
paulb@749 | 185 | resource), whilst maintaining a reference to the <code>connection</code> |
paulb@749 | 186 | provided.</p> |
paulb@749 | 187 | |
paulb@749 | 188 | <p>Resources wishing to access the database connection would use code like |
paulb@749 | 189 | the following:</p> |
paulb@749 | 190 | |
paulb@749 | 191 | <pre> |
paulb@749 | 192 | def respond(self, trans): |
paulb@749 | 193 | |
paulb@749 | 194 | # Some code... |
paulb@749 | 195 | |
paulb@749 | 196 | connection = trans.get_attributes()["store"] |
paulb@749 | 197 | </pre> |
paulb@749 | 198 | |
paulb@749 | 199 | <p>Should an alternative attribute name be required, such a name may be |
paulb@749 | 200 | provided as an additional argument when initialising the |
paulb@749 | 201 | <code>StoreSelector</code>; for example:</p> |
paulb@749 | 202 | |
paulb@749 | 203 | <pre> |
paulb@749 | 204 | def get_site_map(connection): |
paulb@749 | 205 | return StoreSelector(MyResource(), connection, "connection") |
paulb@749 | 206 | </pre> |
paulb@749 | 207 | |
paulb@749 | 208 | <h4>Further Reading</h4> |
paulb@749 | 209 | |
paulb@749 | 210 | <p>The <a |
paulb@749 | 211 | href="../apidocs/public/WebStack.Resources.Selectors.StoreSelector-class.html">API |
paulb@749 | 212 | documentation</a> for the <code>StoreSelector</code> class provides |
paulb@749 | 213 | additional information, and the <a href="integrating.html">"Integrating with |
paulb@749 | 214 | Other Systems"</a> document describes related topics.</p> |
paulb@749 | 215 | |
paulb@749 | 216 | </div> |
paulb@749 | 217 | |
paulb@749 | 218 | </body></html> |