Author: hlship
Date: Tue Jan 16 19:38:16 2007
New Revision: 496924

URL: http://svn.apache.org/viewvc?view=rev&rev=496924
Log:
Add ideas about total reloading

Modified:
    
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html
    tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml

Modified: 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html?view=diff&rev=496924&r1=496923&r2=496924
==============================================================================
--- 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html 
(original)
+++ 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.html 
Tue Jan 16 19:38:16 2007
@@ -5179,10 +5179,11 @@
 <div tiddler="EnvironmentalServices" modifier="HowardLewisShip" 
modified="200609260145" created="200609251547" tags="">Frequently, different 
components need to //cooperate// during the rendering process.\n\nThis is an 
established pattern from Tapestry 4, which an enclosing component provides 
services to the components it encloses. By //encloses// we mean, any components 
that are rendered as part of the Form's body; give the use of the 
Block/~RenderBlock components, this can not be determined statically, but is 
instead determined dynamically, as part of the rendering process.\n\nThe 
canoncial example of this pattern is Form component, and the complex 
relationship it has with each form element component it encloses.\n\nIn 
Tapestry 4, this mechanism was based on the ~IRequestCycle which could store 
named attributes. The service providing component would store itself into the 
cycle using a well known name, and service consuming components would retrieve 
the service using the sam
 e well known name.\n\nFor Tapestry 5, this will be formalized. A new service 
will be used to manage this information:\n\n{{{\npublic interface 
Enviroment\n{\n  &lt;T&gt; T push(Class&lt;T&gt; type, T instance);\n\n  
&lt;T&gt; peek(Class&lt;T&gt; type);\n\n  &lt;T&gt; T pop(Class&lt;T&gt; 
type);\n}\n}}}\n\nThe Environment is unique to a request.</div>
 <div tiddler="FocusOnTesting" modifier="HowardLewisShip" 
modified="200611241954" created="200611241954" tags="">I'm still not at the 
stage of test first, but with every line of code I write, I am thiking about 
how I will test that line of code.  Tapestry uses EasyMock extensively, and 
there's lots of existing code examples to work with.\n\n!Dont Despair\n\nI 
occasionally get exhausted by the amount of test code I write for simple chunks 
of code.  And I inevitably find a broken line of code that would be a major 
pain to locate inside a running application, but easy inside a unit test. Keep 
your eyes on the big picture.</div>
 <div tiddler="FormProcessing" modifier="HowardLewisShip" 
modified="200609211540" created="200609210203" tags="forms">Form processing in 
Tapestry 4 had certain strengths and limitations.\n\nBasically, any action 
framework that can do a simple mapping from query parameters to bean property 
names has advantages in terms of simple forms, and Tapestry 4's approach has 
huge advantages on more complex forms (with some considerable developer and 
framework overhead).\n\nWith a direct mapping of query parameter names to bean 
names, each query parameter becomes self describing. You map query parameters 
to property of some well known bean. You do simple conversions from strings to 
other types (typically, ints and dates and the like). You drop query parameters 
that don't match up. You leave a lot of validation and other plumbing (such as 
getting those values into your DataTransferObjects) to the developer.\n\nBut 
you never see a ~StaleLinkException.\n\nYou also have some unwanted loophol
 es in your application in that //any// property can be updated through the 
URL. This is //one step// towards a security hole.\n\n!Tapestry 4 
Approach\n\nEvery form component, as it renders, asks the Form that encloses it 
to provide a client id.  The terminology is a little messed; client id is the 
unique (within the form) name for //one rendering// of the component. If the 
component renders multiple times, because of loops, each rendering gets a 
unique name.  This becomes the &lt;input&gt;'s name attribute, and ultimately, 
the query parameter name.\n\nTapestry attempts to make the client id match the 
(user provided) component id. This is not always possible, especially in a 
loop, in which case a numeric suffix may be appended to the id to (help) ensure 
uniqueness.\n\nOn render, a sequence of //component activations// occur, guided 
by the normal render sequence. The exact sequence of activations guides\nthe 
production of client ids.\n\nUsing more advanced Tapestry techniques,
  including loops, conditionals and the Block/RenderBlock combo, the exact set 
of components and\ncomponent activations that will occur for a given rendering 
of a given form can not be predicted statically. Tapestry must actually render 
out the form\nto discover all of these.\n\nIn fact, while the Form component is 
producing this series of client ids, it builds up the list and stores it into 
the rendered page as a hidden form field. It will need it later, when the 
client-side form is submitted back to the server.\n\nAn advantage of this 
approach is the disconnect between the query parameter names (the client ids) 
and the objects and properties being editted. Often the client ids will be 
//mneumonic// for the properties, but aren't directly mapped to them. Only the 
components responsible for each query parameter know how to validate the 
submitted value, and what property of which object will need to be 
updated.\n\nWhen a form submission occurs, we want to ensure that each quer
 y parameter value read out of the request is applied to the correct property 
of the correct object. There's a limit to how much Tapestry can help here 
(because it has only a casual knowledge of this aspect of the application 
structure).\n\nDuring this submission process, which endded up with the curious 
name, //rewind phase//, Tapestry must do two things:\n* Activate each 
component, such that the component may re-determine its client id, read its 
parameter, and update its page property\n* Validate that the process has not 
been comprimised by a change of server side state\n\nThat second element is a 
tricky one; things can go wonky if a race condition occurs between two users. 
For example, lets take a simple invoice and line item model. If users A and B 
both read the same invoice, user A adds a line item, and user B changes a line 
item ... we can have a problem when user B submits the form. Now that there are 
three line items (not two) in the form, there will be extra componen
 t activations to process query parameters that don't exist in the request. 
\n\nThis scenario can occur whenever the processing of the form submission is 
driven by server-side data that can change between request.\n\nTapestry detects 
this as a difference in the sequence of client ids allocated, and throws a 
~StaleLinkException, which is very frustrating for developers to comprehend and 
fix.\n\nThere are also other edge cases for different race conditions where 
data is applied to the wrong server-side objects.\n\nThe Tapestry 3 ~ListEdit 
component, which evolved into the  Tapestry 4 For component, attempts to 
address this by serializing a series of //object ids// into the form (as a 
series of hidden fields). This requires a bit of work on the part of the 
developer to provide an ~IPrimaryKeyConverter that can help convert objects to 
ids (when rendering) and ids back to objects (during form 
submission).\n\nGenerally speaking, the Tapestry 4 approach represents layers 
of kludge o
 n layers of kludge. It works, it gets the job done, it can handle some very 
complex situations, but it is less than ideal.\n\n!Tapestry 5\n\nThe goal here 
is to capture the series of //component activations//, along with any 
significant page state changes, during the render.\n\nThese activations will be 
a series of //commands//.  For each component activation there will be two 
commands:  the first command will be used to inform the component of its client 
id (this command executes during render and during form submission). The second 
command will request that the client handle the form submission (this command 
executes only during form submission).\n\nThe serialized series of commands is 
stored as a hidden form field.\n\nThere's a lot of API to be figured out, 
especially the relationship between the form components and the form 
itself.\n\nFurther, a lot of what the Tapestry 4 For component does, in terms 
of serializing dynamic page state, will need to fold into this as well.
 \n\nThe end result will be a single hidden field with a big MIME string inside 
it ... but compared to the Tapestry 4 Form component (which has to write out 
many hidden fields) the whole will be less than the sum of the parts ... due to 
the overhead of serialization and gzip compression.\n\n\n\n\n\n\n</div>
+<div tiddler="FullReload" modifier="HowardLewisShip" modified="200701161450" 
created="200701161450" tags="">It has occured to me that by adding yet another 
smart class loader, we could possibly set up a system where we track date time 
modified on all the modules, service interfaces, and implementation files 
loaded by the Registry, such that changes to any of the files could result in a 
kind of &quot;soft reload&quot;, where we reload the changed files and 
construct and use a new Registry.</div>
 <div tiddler="InvisibleInstrumentation" modifier="HowardLewisShip" 
modified="200610201803" created="200610201802" tags="">A feature of Tapestry 4 
where the component id, type and parameters were &quot;hidden&quot; inside 
ordinary HTML tags.\n\nThis will show up inside Tapestry 5 pretty soon, and 
look something like:\n{{{\n&lt;span t:type=&quot;If&quot; 
t:test=&quot;prop:showWarning&quot; class=&quot;warning&quot;&gt; \n  . . 
.\n&lt;/span&gt;\n}}}</div>
 <div tiddler="LogicalPageName" modifier="HowardLewisShip" 
modified="200610081330" created="200610081330" tags="">A logical page name is 
the name of a page as it is represented in a URI.\n\nInternally, Tapestry 
operates on pages using full qualified class names. Technically, the FQCN is 
the class of the page's root element, but from an end developer point of view, 
the root element is the page.\n\nThe logical page name must be converted to a 
fully qualified class name.\n\nA set of LibraryMappings are used.  Each library 
mapping is used to express a folder name, such as &quot;core&quot;, with a Java 
package name, such as org.apache.tapestry.corelib.  For pages, the page name is 
searched for in the pages sub-package (i.e., 
org.apache.tapestry.corelib.pages).  Component libraries have unique folder 
names mapped to root packages that contain the pages (and components, and 
mixins) of that library.\n\nWhen there is no folder name, the page is expected 
to be part of the application, 
 under the pages sub-package of the application's root package.\n\nIf not found 
there, as a special case, the name is treated as if it were prefixed with 
&quot;core/&quot;.  This allows access to the core pages (and more importantly, 
components -- the search algorithm is the same).\n\nFinally, pages may be 
organized into folders.  These folders become further sub-packages. Thus as 
page name of &quot;admin/EditUsers&quot; may be resolved to class 
org.example.myapp.pages.admin.EditUsers.\n\n</div>
 <div tiddler="MainMenu" modifier="HowardLewisShip" modified="200609210701" 
created="200609210643" tags="">MasterIndex\n[[RSS 
feed|tap5devwiki.xml]]\n\n[[Tapestry 5 
Home|http://tapestry.apache.org/tapestry5/]]\n[[Howard's 
Blog|http://howardlewisship.com/blog/]]\n\n[[Formatting 
Help|http://www.blogjones.com/TiddlyWikiTutorial.html#EasyToEdit%20Welcome%20NewFeatures%20WhereToFindHelp]]</div>
-<div tiddler="MasterIndex" modifier="HowardLewisShip" modified="200701051919" 
created="200609202214" tags="">Top level concepts within Tapestry 5.\n\nA 
//meta-note//: This is where new ideas are first explained, usually before 
being implemented. In many cases, the final implementation is\nnot a perfect 
match for the notes. That's OK ... as long as the official Maven documentation 
does a good job. It's not reasonable to expect developers to jump back in here 
and dot every i and cross every t if they're already expected to generate good 
Maven documentation.\n\n* PropBinding -- Notes on the workhorse 
&quot;prop:&quot; binding prefix\n* TypeCoercion -- How Tapestry 5 extensibly 
addresses type conversion\n* FormProcessing\n* DynamicPageState -- tracking 
changes to page state during the render\n* EnvironmentalServices -- how 
components cooperate during page render\n* ComponentMixins -- A new fundamental 
way to build web functionality\n* RequestTypes -- Requests, request processing
 , URL formats\n* ComponentTemplates -- Issues about Component Templates\n* 
DeveloperProcedures -- Your a Tapestry committer ... how do you makes 
changes?\n* SmartDefaults -- do even more with event less\n* RandomIdeas -- 
stuff that doesn't fit elsewhere\n* ProblemsNeedingSolutions\n* 
ComponentDocumentation -- Generating Documentation about Components\n* 
TapestryLookAndFeel -- Default CSS\n* [[Assets]]\n* CaseInsensitivity -- case 
in URLs should not matter\n\n</div>
+<div tiddler="MasterIndex" modifier="HowardLewisShip" modified="200701161448" 
created="200609202214" tags="">Top level concepts within Tapestry 5.\n\nA 
//meta-note//: This is where new ideas are first explained, usually before 
being implemented. In many cases, the final implementation is\nnot a perfect 
match for the notes. That's OK ... as long as the official Maven documentation 
does a good job. It's not reasonable to expect developers to jump back in here 
and dot every i and cross every t if they're already expected to generate good 
Maven documentation.\n\n* PropBinding -- Notes on the workhorse 
&quot;prop:&quot; binding prefix\n* TypeCoercion -- How Tapestry 5 extensibly 
addresses type conversion\n* FormProcessing\n* DynamicPageState -- tracking 
changes to page state during the render\n* EnvironmentalServices -- how 
components cooperate during page render\n* ComponentMixins -- A new fundamental 
way to build web functionality\n* RequestTypes -- Requests, request processing
 , URL formats\n* ComponentTemplates -- Issues about Component Templates\n* 
DeveloperProcedures -- Your a Tapestry committer ... how do you makes 
changes?\n* SmartDefaults -- do even more with event less\n* RandomIdeas -- 
stuff that doesn't fit elsewhere\n* ProblemsNeedingSolutions\n* 
ComponentDocumentation -- Generating Documentation about Components\n* 
TapestryLookAndFeel -- Default CSS\n* [[Assets]]\n* CaseInsensitivity -- case 
in URLs should not matter\n* FullReload -- Why limit reloading to just 
components?\n\n</div>
 <div tiddler="OGNL" modifier="HowardLewisShip" modified="200610071249" 
created="200609202254" tags="">The [[Object Graph Navigation 
Library|http://ognl.org]] was an essential part of Tapestry 4.\n\nOGNL is both 
exceptionally powerful (especially the higher order things it can do, such as 
list selections and projections). However, for the highest\nend sites, it is 
also a performance problem, both because of its heavy use of reflection, and 
because it uses a lot of code inside synchronized blocks.\n\nIt will be 
optional in Tapestry 5. I believe it will not be part of the tapestry-core, but 
may be packaged as tapestry-ognl.\n\nThe &quot;prop:&quot; binding prefix is an 
effective replacement for OGNL in Tapestry 5.   See PropBinding.\n</div>
 <div tiddler="PageRenderRequest" modifier="HowardLewisShip" 
modified="200610081333" created="200610071313" tags="">Page render requests are 
requests used to render a specific page.  //render// is the term meaning to 
compose the HTML response to be sent to the client. Note: HTML is used here 
only as the most common case, other markups are entirely possible.\n\nIn many 
cases, pages are stand-alone.  No extra information in the URL is necesarry to 
render them.  PersistentProperties of the page will factor in to the rendering 
of the page.\n\nIn specific cases, a page needs to render within a particular 
context. The most common example of this is a page that is used to present a 
specific instance of a database persistent entity. In such a case, the page 
must be combined with additional data, in the URL, to identify the specific 
entity to access and render.\n\n! URI 
Format\n\n{{{\n/page-name.html/id\n}}}\n\nHere &quot;page-name&quot; is the 
LogicalPageName for the page. \n\nThe &q
 uot;.html&quot; file extension is used as a delimiter between the page name 
portion of the URI, and the context portion of the URI. This is necessary 
because it is not possible (given the plethora of libraries and folders) to 
determine how many slashes will appear in the URI.\n\nThe context consists of 
one ore more ids (though a single id is the normal case). The id is used to 
identify the specific data to be displayed. Further, a page may require 
multiple ids, which will separated with slashes. Example: 
/admin/DisplayDetail.html/loginfailures/2006\n\nNote that these context values, 
the ids, are simply //strings//. Tapestry 4 had a mechanism, the DataSqueezer, 
that would encode the type of object with its value, as a single string, and 
convert it back. While seemingly desirable, this facility was easy to abuse, 
resulting in long and extremely ugly URIs.\n\nAny further information needed by 
Tapestry will be added to the URI as query parameters. This may include things 
like us
 er locale, persistent page properties, applicaition flow identifiers, or 
anything else we come up with.\n\n! Request Processing\n\nOnce the page and id 
parameters are identified, the corresponding page will be loaded.\n\nTapestry 
will fire two events before rendering the page.\n\nThe first event is of type 
&quot;setupPageRender&quot;.  This allows the page to process the context (the 
set of ids). This typically involves reading objects from an external 
persistent store (a database)\nand storing those objects into transient page 
properties, in expectaion of the render.\n\nThe @SetupPageRender annotation 
marks a method to be invoked when this event is triggered.  The method may take 
one or more strings, or an array of strings, as parameters; these will be\nthe 
context values.  The method will normally return void.  Other values are 
''TBD''. It may also take other simple types, which will be coerced from the 
string [EMAIL PROTECTED] setup(long id)\n{\n  . .
  .\n}\n}}}\n\n\n\nThe second event is of type &quot;pageValidate&quot;.  It 
allows the page to decide whether the page is valid for rendering at this time. 
This most often involves a check to see if the user is logged into the 
application, and has the necessary privileges to display the contents of the 
page.  User identity and privileges are //not// concepts built into Tapestry, 
but are fundamental to the majority of Tapestry applications.</div>
 <div tiddler="ProblemsNeedingSolutions" modifier="HowardLewisShip" 
modified="200701032351" created="200611230401" tags="">There are a few things 
that I'm concerned about.\n\n!Render Complexity\n\nAll those states in the 
render component state machine may be a little much, especially 
~PreBeginRender, ~BeginRender and ~PostBeginRender.  In addition, it doesn't 
work for a case I'm interested in ... for link components, I'd like to use the 
RenderInformals mixin, but also support a disable parameter that turns off the 
&lt;a&gt; tag (but still renders the body).  The state machine currently is set 
up so that returning false in any of the ~BeginRender states skips all the way 
to ~AfterRender, bypassing the template and/or body.\n\nStill don't have a 
perfect solution for the above (it may not be solvable via mixins, which may 
show limitations in the component/mixin model).  I have added a @MixinAfter 
annotation which simplifies the state machine somewhat.</div>

Modified: 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml?view=diff&rev=496924&r1=496923&r2=496924
==============================================================================
--- 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml 
(original)
+++ 
tapestry/tapestry5/tapestry-project/trunk/src/site/resources/tap5devwiki.xml 
Tue Jan 16 19:38:16 2007
@@ -6,27 +6,33 @@
 <description>The quick and dirty one-stop shopping of random ideas for 
Tapestry 5.</description>
 <language>en-us</language>
 <copyright>Copyright 2007 HowardLewisShip</copyright>
-<pubDate>Fri, 05 Jan 2007 19:35:21 GMT</pubDate>
-<lastBuildDate>Fri, 05 Jan 2007 19:35:21 GMT</lastBuildDate>
+<pubDate>Tue, 16 Jan 2007 14:51:05 GMT</pubDate>
+<lastBuildDate>Tue, 16 Jan 2007 14:51:05 GMT</lastBuildDate>
 <docs>http://blogs.law.harvard.edu/tech/rss</docs>
 <generator>TiddlyWiki 2.0.11</generator>
 <item>
-<title>CaseInsensitivity</title>
-<description>One aspect of &quot;pretty&quot; URLs for Tapestry pages is that 
case should not matter.  The user should be able to manually type a URL without 
respect to case, and have it //just work//.  Turns out that's hard on a number 
of fronts.&lt;br /&gt;&lt;br /&gt;! Page Names&lt;br /&gt;&lt;br /&gt;In 
Tapestry 4 and in the current Tapestry 5 code base, that is a problem.  
Tapestry starts with a page name, and uses that to hunt around and locate the 
page class and from there, the page template, etc.&lt;br /&gt;&lt;br /&gt;That 
hunting around tends to be problematic, because ClassLoader.getResource() is 
case //specific//.  In addition, ClassLoader doesn't directly provide any way 
to introspect the available classes.&lt;br /&gt;&lt;br /&gt;You'd think that 
you could, as a page is first accesssed, record its name in a case insensitve 
cache somewhere.  However, that doesn't work.  First, in a cluster, the server 
handling the request may simply never have handled a request 
 for that page before, so it won't have an up-to date cache.  Likewise, after a 
server restart, existing requests (possibly cached in a browser's bookmarks) 
&lt;br /&gt;&lt;br /&gt;However, I've been doing some research.  
ClassLoader.getResources() , passed a folder name (such as 
&quot;org/example/myapp/pages/&quot;) will yield one or more URLs for the 
folders.  Some of these will be URLs for file systems, some will be URLs for 
JARs.  You can differentiate by the value returned from 
URL.openConnection().&lt;br /&gt;&lt;br /&gt;For file system URLs, opening the 
stream provides a list of the files and folders for that package.  Using this, 
we can identify the protential classes, and identify sub-folders/sub-packages 
to recursively scan.&lt;br /&gt;&lt;br /&gt;For JAR URLs, we can cast to 
JARURLConnection and obtain the JarFile instance for the entire JAR.  From 
there we can obtain a list of entries.&lt;br /&gt;&lt;br /&gt;Combining these 
two approaches should allow us, at appli
 cation startup, to locate all page instances.  We'll be able to build a 
case-insensitive mapping from logical page name to Java class name.&lt;br 
/&gt;&lt;br /&gt;! Component Ids&lt;br /&gt;&lt;br /&gt;Component ids and id 
paths show up in some URLs (primarily action URLs, but even so). As currently 
implemented, ids are case sensitive. With some work, it should be possible to 
make accessing a component by its id, or id path, case insensitive.  This 
should include errors if two components have the same case-insensitive 
id.&lt;br /&gt;&lt;br /&gt;! Query Parameters&lt;br /&gt;&lt;br /&gt;Not sure 
this is as relevant, because the types of URLs that matter will usually not 
include any query parameters.  In terms of form submissions ... well, the 
entire client side is wired case sensitivly, so making form submissions case 
inensitive seems like a useless exercise.</description>
-<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#CaseInsensitivity</link>
-<pubDate>Fri, 05 Jan 2007 19:34:38 GMT</pubDate>
+<title>FullReload</title>
+<description>It has occured to me that by adding yet another smart class 
loader, we could possibly set up a system where we track date time modified on 
all the modules, service interfaces, and implementation files loaded by the 
Registry, such that changes to any of the files could result in a kind of 
&quot;soft reload&quot;, where we reload the changed files and construct and 
use a new Registry.</description>
+<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#FullReload</link>
+<pubDate>Tue, 16 Jan 2007 14:50:26 GMT</pubDate>
 </item>
 <item>
 <title>MasterIndex</title>
-<description>Top level concepts within Tapestry 5.&lt;br /&gt;&lt;br /&gt;A 
//meta-note//: This is where new ideas are first explained, usually before 
being implemented. In many cases, the final implementation is&lt;br /&gt;not a 
perfect match for the notes. That's OK ... as long as the official Maven 
documentation does a good job. It's not reasonable to expect developers to jump 
back in here and dot every i and cross every t if they're already expected to 
generate good Maven documentation.&lt;br /&gt;&lt;br /&gt;* PropBinding -- 
Notes on the workhorse &quot;prop:&quot; binding prefix&lt;br /&gt;* 
TypeCoercion -- How Tapestry 5 extensibly addresses type conversion&lt;br 
/&gt;* FormProcessing&lt;br /&gt;* DynamicPageState -- tracking changes to page 
state during the render&lt;br /&gt;* EnvironmentalServices -- how components 
cooperate during page render&lt;br /&gt;* ComponentMixins -- A new fundamental 
way to build web functionality&lt;br /&gt;* RequestTypes -- Requests, requ
 est processing, URL formats&lt;br /&gt;* ComponentTemplates -- Issues about 
Component Templates&lt;br /&gt;* DeveloperProcedures -- Your a Tapestry 
committer ... how do you makes changes?&lt;br /&gt;* SmartDefaults -- do even 
more with event less&lt;br /&gt;* RandomIdeas -- stuff that doesn't fit 
elsewhere&lt;br /&gt;* ProblemsNeedingSolutions&lt;br /&gt;* 
ComponentDocumentation -- Generating Documentation about Components&lt;br 
/&gt;* TapestryLookAndFeel -- Default CSS&lt;br /&gt;* [[Assets]]&lt;br /&gt;* 
CaseInsensitivity -- case in URLs should not matter&lt;br /&gt;&lt;br 
/&gt;</description>
+<description>Top level concepts within Tapestry 5.&lt;br /&gt;&lt;br /&gt;A 
//meta-note//: This is where new ideas are first explained, usually before 
being implemented. In many cases, the final implementation is&lt;br /&gt;not a 
perfect match for the notes. That's OK ... as long as the official Maven 
documentation does a good job. It's not reasonable to expect developers to jump 
back in here and dot every i and cross every t if they're already expected to 
generate good Maven documentation.&lt;br /&gt;&lt;br /&gt;* PropBinding -- 
Notes on the workhorse &quot;prop:&quot; binding prefix&lt;br /&gt;* 
TypeCoercion -- How Tapestry 5 extensibly addresses type conversion&lt;br 
/&gt;* FormProcessing&lt;br /&gt;* DynamicPageState -- tracking changes to page 
state during the render&lt;br /&gt;* EnvironmentalServices -- how components 
cooperate during page render&lt;br /&gt;* ComponentMixins -- A new fundamental 
way to build web functionality&lt;br /&gt;* RequestTypes -- Requests, requ
 est processing, URL formats&lt;br /&gt;* ComponentTemplates -- Issues about 
Component Templates&lt;br /&gt;* DeveloperProcedures -- Your a Tapestry 
committer ... how do you makes changes?&lt;br /&gt;* SmartDefaults -- do even 
more with event less&lt;br /&gt;* RandomIdeas -- stuff that doesn't fit 
elsewhere&lt;br /&gt;* ProblemsNeedingSolutions&lt;br /&gt;* 
ComponentDocumentation -- Generating Documentation about Components&lt;br 
/&gt;* TapestryLookAndFeel -- Default CSS&lt;br /&gt;* [[Assets]]&lt;br /&gt;* 
CaseInsensitivity -- case in URLs should not matter&lt;br /&gt;* FullReload -- 
Why limit reloading to just components?&lt;br /&gt;&lt;br /&gt;</description>
 <link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#MasterIndex</link>
-<pubDate>Fri, 05 Jan 2007 19:19:59 GMT</pubDate>
+<pubDate>Tue, 16 Jan 2007 14:48:59 GMT</pubDate>
+</item>
+<item>
+<title>CaseInsensitivity</title>
+<description>One aspect of &quot;pretty&quot; URLs for Tapestry pages is that 
case should not matter.  The user should be able to manually type a URL without 
respect to case, and have it //just work//.  Turns out that's hard on a number 
of fronts.&lt;br /&gt;&lt;br /&gt;! Page Names&lt;br /&gt;&lt;br /&gt;In 
Tapestry 4 and in the current Tapestry 5 code base, that is a problem.  
Tapestry starts with a page name, and uses that to hunt around and locate the 
page class and from there, the page template, etc.&lt;br /&gt;&lt;br /&gt;That 
hunting around tends to be problematic, because ClassLoader.getResource() is 
case //specific//.  In addition, ClassLoader doesn't directly provide any way 
to introspect the available classes.&lt;br /&gt;&lt;br /&gt;You'd think that 
you could, as a page is first accesssed, record its name in a case insensitve 
cache somewhere.  However, that doesn't work.  First, in a cluster, the server 
handling the request may simply never have handled a request 
 for that page before, so it won't have an up-to date cache.  Likewise, after a 
server restart, existing requests (possibly cached in a browser's bookmarks) 
&lt;br /&gt;&lt;br /&gt;However, I've been doing some research.  
ClassLoader.getResources() , passed a folder name (such as 
&quot;org/example/myapp/pages/&quot;) will yield one or more URLs for the 
folders.  Some of these will be URLs for file systems, some will be URLs for 
JARs.  You can differentiate by the value returned from 
URL.openConnection().&lt;br /&gt;&lt;br /&gt;For file system URLs, opening the 
stream provides a list of the files and folders for that package.  Using this, 
we can identify the protential classes, and identify sub-folders/sub-packages 
to recursively scan.&lt;br /&gt;&lt;br /&gt;For JAR URLs, we can cast to 
JARURLConnection and obtain the JarFile instance for the entire JAR.  From 
there we can obtain a list of entries.&lt;br /&gt;&lt;br /&gt;Combining these 
two approaches should allow us, at appli
 cation startup, to locate all page instances.  We'll be able to build a 
case-insensitive mapping from logical page name to Java class name.&lt;br 
/&gt;&lt;br /&gt;! Component Ids&lt;br /&gt;&lt;br /&gt;Component ids and id 
paths show up in some URLs (primarily action URLs, but even so). As currently 
implemented, ids are case sensitive. With some work, it should be possible to 
make accessing a component by its id, or id path, case insensitive.  This 
should include errors if two components have the same case-insensitive 
id.&lt;br /&gt;&lt;br /&gt;! Query Parameters&lt;br /&gt;&lt;br /&gt;Not sure 
this is as relevant, because the types of URLs that matter will usually not 
include any query parameters.  In terms of form submissions ... well, the 
entire client side is wired case sensitivly, so making form submissions case 
inensitive seems like a useless exercise.</description>
+<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#CaseInsensitivity</link>
+<pubDate>Fri, 05 Jan 2007 19:34:00 GMT</pubDate>
 </item>
 <item>
 <title>ComponentTemplates</title>
 <description>There are some issues related to component templates.&lt;br 
/&gt;&lt;br /&gt;Firstly, people are really interested in seeing the return of 
InvisibleInstrumentation.  =That is coming.= That is now available.&lt;br 
/&gt;&lt;br /&gt;Secondly, the idea that templates are well-formed XML 
documents is causing some issues.&lt;br /&gt;&lt;br /&gt;The problem is related 
to entities and doctypes.&lt;br /&gt;&lt;br /&gt;Unless you provide a doctype 
for the template, 
[[entities|http://www.htmlhelp.com/reference/html40/entities/]] don't work; 
they result in template parse errors.&lt;br /&gt;&lt;br /&gt;If you provide a 
standard doctype, say&lt;br /&gt;{{{&lt;br /&gt; &lt;!DOCTYPE HTML PUBLIC 
&quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot;&lt;br /&gt;            
&quot;http://www.w3.org/TR/REC-html40/loose.dtd&quot;&gt;&lt;br /&gt;}}}&lt;br 
/&gt;&lt;br /&gt;You also get parse errors, because the DTD does some odd 
things with comments that the Java SAX parser doesn't seem to 
 understand.&lt;br /&gt;&lt;br /&gt;I've had better luck with the XHTML 
doctype:&lt;br /&gt;{{{&lt;br /&gt;&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD 
XHTML 1.0 Transitional//EN&quot;&lt;br 
/&gt;&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;&lt;br
 /&gt;}}}&lt;br /&gt;&lt;br /&gt;But this doesn't render quite the way I want 
it to.&lt;br /&gt;&lt;br /&gt;Further, entities in the text are converted to 
unicode by the parser, then converted to //numeric// entities on output.  Not 
quite WYSIWYG and potentially confusing.&lt;br /&gt;&lt;br /&gt;It may be 
necessary to discard SAX and build a limited XML parser that allows entities to 
be passed through unchanged (they would become a special type of document 
token).&lt;br /&gt;&lt;br /&gt;Lastly, the question is how to get the correct 
DOCTYPE into the rendered output, espcially in the common case that a Border 
component provides the outer tags, as is common in Tapestry 4.  This may have 
to be configured as a ann
 otation on page classes.&lt;br /&gt;&lt;br /&gt;! Template Location&lt;br 
/&gt;&lt;br /&gt;Concensus is building that templates should //not//  have a  
{{{.html}}} extension, but something specific to Tapestry, perhaps {{{.tap}}} 
or {{{.tsp}}}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Further, there are invalid, 
but present, security concerns that the templates should live on the classpath 
or in WEB-INF, but not in the root folder.  Both of these issues would simplify 
things for Tapestry.&lt;br /&gt;</description>
 
<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#ComponentTemplates</link>
-<pubDate>Fri, 05 Jan 2007 19:19:01 GMT</pubDate>
+<pubDate>Fri, 05 Jan 2007 19:19:00 GMT</pubDate>
 </item>
 <item>
 <title>SmartDefaults</title>
@@ -128,12 +134,6 @@
 <category>events</category>
 
<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#ComponentEvent</link>
 <pubDate>Sun, 08 Oct 2006 13:59:00 GMT</pubDate>
-</item>
-<item>
-<title>ComponentActionRequest</title>
-<description>Component actions are actions that reflect user interaction with 
a component within a page. Again, this falls into several broad 
categories:&lt;br /&gt;&lt;br /&gt;* Links that perform a server-side action, 
and result in a page refresh, or a new page being displayed.&lt;br /&gt;* Ajax 
style links, which perform a server-side action, and refresh only part of the 
page.&lt;br /&gt;* Forms which perform a server-side action, followed by a page 
refresh (or new page being displayed).&lt;br /&gt;* Ajax style forms, which 
trigger an action, followed by a refresh of part of the page.&lt;br /&gt;* 
Other user interactions, which result in a server side action, and a partial 
page refresh.&lt;br /&gt;&lt;br /&gt;In all of these cases, one or more 
ComponentEvents is fired. The result of ComponentEvent determines whether a 
partial page render or a full page render occurs.&lt;br /&gt;&lt;br /&gt;In the 
later case, a client side redirect is sent, to force the browser to initial 
 a new PageRenderRequest.  This addresses an issue in Tapestry 4, in that 
following a link or form submission, the URL would indicate details about the 
previous page, not the newly displayed page, and clicking the browser refresh 
button could cause a server side operation to occur again (which would often be 
quite undersirable).&lt;br /&gt;&lt;br /&gt;!URI Format&lt;br /&gt;&lt;br 
/&gt;{{{&lt;br /&gt;/page-name.event-type/component-id-path/id&lt;br 
/&gt;}}}&lt;br /&gt;&lt;br /&gt;Here page-name is the LogicalPageName.  The 
event-type is a string that identifies the type of event (and will ultimately 
be used to select an event handler method).  &lt;br /&gt;&lt;br /&gt;The 
component-id-path is a dot-separated series of component ids, used to identify 
a specific component within the overall page.&lt;br /&gt;&lt;br /&gt;The id is 
optional, and may be repeated. The id value or values will be provided to the 
event handler method.&lt;br /&gt;&lt;br /&gt;Example: /Login.submit/form  
 (the URI for a form component on page Login).&lt;br /&gt;&lt;br /&gt;Example: 
/admin/UserProfile/action/menu.delete/37  (component menu.delete of the 
UserProfile page, with an id of 37).&lt;br /&gt;</description>
-<link>http://tapestry.apache.org/tapestry5/tap5devwiki.html#ComponentActionRequest</link>
-<pubDate>Sun, 08 Oct 2006 13:35:00 GMT</pubDate>
 </item>
 </channel>
 </rss>


Reply via email to