You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@velocity.apache.org by nb...@apache.org on 2008/05/28 02:40:38 UTC

svn commit: r660766 - in /velocity/tools/trunk/xdocs: creatingtools.xml frameworks.xml

Author: nbubna
Date: Tue May 27 17:40:38 2008
New Revision: 660766

URL: http://svn.apache.org/viewvc?rev=660766&view=rev
Log:
fill in some more missing docs

Modified:
    velocity/tools/trunk/xdocs/creatingtools.xml
    velocity/tools/trunk/xdocs/frameworks.xml

Modified: velocity/tools/trunk/xdocs/creatingtools.xml
URL: http://svn.apache.org/viewvc/velocity/tools/trunk/xdocs/creatingtools.xml?rev=660766&r1=660765&r2=660766&view=diff
==============================================================================
--- velocity/tools/trunk/xdocs/creatingtools.xml (original)
+++ velocity/tools/trunk/xdocs/creatingtools.xml Tue May 27 17:40:38 2008
@@ -28,31 +28,142 @@
 
     <body>
 
-    <section name="Overview">
-        <p class="note">
-            This page is still unfinished.
-            <a href="index.html#Contribution">Help is welcome!</a>
+    <section name="Contents">
+        <p>
+            This page contains advice and instructions for
+            creating your own "tools".  Of course, almost any POJO can
+            be used as a tool, but there are ways to make your tools
+            much more useful, maintainable and secure.  The tips here
+            should help you do that. If you have tips to add,
+            email them to our 
+            <a href="http://velocity.apache.org/contact.html">development mailing list</a>.
         </p>
+        <ol>
+        <li>
+            <a href="#Conventions">Conventions</a>
+            <ol>
+            <li><a href="#">Keys/Names</a></li>
+            <li><a href="#">Properties</a></li>
+            </ol>
+        </li>
+        <li><a href="#Annotations">Annotations</a></li>
+        <li>
+            <a href="#Support_Classes">Support Classes</a>
+            <ol>
+            <li><a href="#Base_Classes">Base Classes</a></li>
+            <li><a href="#Utility_Classes">Utility Classes</a></li>
+            </ol>
+        </li>
+        <li>
+            <a href="#Designing_Template-Friendly_Interfaces">Template-Friendly Interfaces</a>
+            <ol>
+            <li><a href="#Be_Robust">Be Robust</a></li>
+            <li><a href="#Be_Flexible">Be Flexible</a></li>
+            <li><a href="#Be_Careful">Be Careful</a></li>
+            <li><a href="#Be_Natural">Be Natural</a></li>
+            </ol>
+        </li>
+        </ol>
     </section>
     <section name="Conventions">
         <subsection name="Tool Keys/Names">
             <p>
-            TODO: talk about [Key]Tool class name, precedence, etc
+            As of VelocityTools 2, the toolbox support can now
+            automatically determine the key name for a tool from
+            its classname.  So, a tool named org.com.FooTool would
+            be assigned the key $foo in your templates, tool
+            named org.com.FooBarTool would be $fooBar, and a tool
+            named org.com.FooBar would be also be $fooBar.
+            </p>
+            <p>
+            If you would prefer to give your org.com.FooBar tool
+            the key $foob, you can use the 
+            <code>org.apache.velocity.tools.config.DefaultKey</code>
+            annotation like this:
+            </p>
+<sourcecode>
+package org.com;
+
+import org.apache.velocity.tools.config.DefaultKey;
+
+@DefaultKey("foob")
+public class FooBar {
+    ...
+}
+</sourcecode>
+            <p>
+            Of course, you or your tool users can always override 
+            your intended key by specifying a different one in
+            the configuration.  Configured key values take precedence
+            over @DefaultKey annotations, and the annotations take
+            precedence over the tool's class name.
             </p>
         </subsection>
         <subsection name="Tool Properties">
             <p>
-            TODO: talk about camelCase config properties, precedence, etc
+            If you want to allow your tool to be configured, you have two
+            options: 
+            <ul>
+            <li>add a public setter for each property</li>
+            <li>add a <code>public void configure(Map props)</code> method</li>
+            </ul>
+            You can, of course, do both, but if you do so keep in mind
+            that the specific setters will be called before the configure()
+            method.
+            The application of configuration properties to specific setters
+            is done using
+            <code>org.apache.commons.beanutils.PropertyUtils</code> from
+            the Commons-BeanUtils project, so the rules follow the typical
+            bean property conventions.
+            </p>
+            <p>
+            One thing to consider here is the scope of your tool and
+            whether or not you want the template authors to be able to
+            alter tool settings from within the template.  Remember,
+            templates can call any public method on any public class,
+            so your specific property setters will be accesible.
+            This is almost always a bad thing for application or session
+            scoped tools as it would make the tool non-threadsafe, 
+            and may or may not matter for a request
+            scoped tool depending on how you use it.  If you cannot rely
+            on your template authors to avoid using those setters or just want
+            to make sure nothing can be changed from within the template,
+            you will probably want to use the configure() method and have
+            your tool extend AbstractLockConfig or one of its subclasses.
+            (This is discussed more later.)
             </p>
         </subsection>
     </section>
     <section name="Annotations">
         <p>
-        TODO: talk about
+        There are three Annotations provided for tool authors:
         <a href="javadoc/org/apache/velocity/tools/config/DefaultKey.html">DefaultKey</a>,
         <a href="javadoc/org/apache/velocity/tools/config/InvalidScope.html">InvalidScope</a> and
         <a href="javadoc/org/apache/velocity/tools/config/ValidScope.html">ValidScope</a>
         </p>
+        <p>
+        As described above, the @DefaultKey annotation is used to specify
+        a default key for your tool.  The @InvalidScope and @ValidScope annotations
+        allow you to restrict the 
+        <a href="javadoc/org/apache/velocity/tools/Scope.html">Scope</a>(s)
+        in which the tool can be used in either negative or positive terms.
+        When described positively using the @ValidScope annotation, the
+        tool may <strong>only</strong> be used in a toolbox with the specified
+        scope. If placed in any other toolbox, an 
+        <code>org.apache.velocity.tools.config.InvalidScopeException</code>
+        will be thrown.  Using @InvalidScope, on the other hand, allows you
+        reject specific scope(s), whilst implicitly allowing any others.
+        </p>
+        <p>
+        Here's a scope annotation example:
+        </p>
+<sourcecode>
+@InvalidScope({Scope.APPLICATION,Scope.SESSION})
+public class PagerTool
+{
+    ...
+}
+</sourcecode>
     </section>
     <section name="Support Classes">
         <subsection name="Base Classes">
@@ -103,16 +214,156 @@
             </p>
         </subsection>
     </section>
-    <section name="Designing Template-friendly Interfaces">
-        <p>
-        Always return null on errors! No Exceptions!
-        </p>
-        <p>
-        TODO: talk about security
-        </p>
+    <section name="Designing Template-Friendly Interfaces">
         <p>
-        TODO: talk about using "subtools" for a fluent API
+        Following a few best-practices can make your tools
+        much more elegant and friendly to template authors.
+        <ul>
+        <li><a href="#Be_Robust">Be robust.</a> Catch exceptions and return <code>null</code> on errors.</li>
+        <li><a href="#Be_Flexible">Be flexible.</a> Have methods accept <code>Object</code> when possible.</li>
+        <li><a href="#Be_Careful">Be careful.</a> Choose scope carefully and be aware of thread safety issues.</li>
+        <li><a href="#Be_Natural">Be natural.</a> Consider using "subtools" to create a fluent API</li>
+        </ul>
         </p>
+        <subsection name="Be Robust">
+            <p>
+            Always return null on errors! No Exceptions!
+            Ok, maybe there are some exceptions if you are sure that's what
+            you want your tool to do.  Just be aware that this will likely surprise
+            the user because uncaught exceptions halt template processing at
+            the point the exception is thrown.  If the output of the template
+            is not buffered, this will result in an awkward, partial rendering.
+            So, if you are going to let an exception through, make sure it
+            is worth halting everything for.  Often it is sufficient to 
+            return null, thus allowing
+            the failed reference to appear in the output like this:
+            </p>
+            <sourcecode>$mytool.somemethod('bad input')</sourcecode>
+            <p>
+            This, of course, assumes that quiet notation is not being used
+            for that reference.  For this reason, it may be prudent to give
+            your tool access to a logging facility in order to log exceptions
+            and make sure important errors are not silently swallowed.
+            Standard tool management for VelocityTools (even just GenericTools)
+            makes the result of <code>velocityEngine.getLog()</code> available
+            to tools as a property under the key "log".  So log access can be
+            added as simply as adding a
+            <code>public void setLog(org.apache.velocity.runtime.log.Log log)</code>
+            method and utilizing the provided Log instance.
+            </p>
+            <p>
+            If you wish to toggle the exception catching or, more importantly,
+            if you prefer to catch exceptions globally with a Velocity Event Handler,
+            then have your tool watch for the "catchExceptions" property.  This
+            is <code>false</code> by default, but if the VelocityEngine has a 
+            MethodExceptionEventHandler configured, then it will be automatically
+            set to <code>true</code>.  Again, just add a 
+            <code>public void setCatchExceptions(boolean catch)</code> method to your
+            tool or watch for the "catchExceptions" property in your
+            <code>public void configure(Map props)</code> method.  See 
+            <a href="javadoc/org/apache/velocity/tools/generic/RenderTool.html">RenderTool</a>
+            for an example of this.
+            </p>
+        </subsection>
+        <subsection name="Be Flexible">
+            <p>
+            Variables in templates are strongly, but dynamically typed.  As the
+            current type (or whole subject of typing) is often not transparently
+            obvious to the person working on the template, it is best to accept
+            <code>Object</code> for most method parameters and handle any necessary
+            conversions in your tool (either through overloading or actual conversion).
+            This way template authors and maintainers don't have to worry about the
+            variable being passed to tool methods.
+            </p>
+            <p>
+            Of course, there may be times when you wish to restrict what a method
+            can accept or when a method is public for use by other classes, not templates.
+            If the method is not meant to be used by the template, ignore this advice
+            and pay careful attention to the <a href="#Be_Careful">advice below</a>.
+            If you have other reasons for restricting the types accepted by a method
+            that you do intend to be used, just be sure to document this plainly so it
+            is easy to discover why the method isn't being called and what parameters
+            it expects to receive.
+            </p>
+        </subsection>
+        <subsection name="Be Careful">
+            <p>
+            The first thing to remember is that all public methods declared
+            in public classes may be called from templates.  If it is imperative
+            that a method not be called from a template, you must either change
+            its permissions, its class's permissions or else put some sort of
+            guard into the implementation of the method that renders it harmless
+            when used by a template.  See the implementation of <code>configure(Map)</code>
+            in <a href="javadoc/org/apache/velocity/tools/generic/AbstractLockConfig.html">AbstractLockConfig</a>
+            for an example of the latter option.
+            </p>
+            <p>
+            The second thing to think about is thread-safety.  If your tool
+            maintains internal state that is in any way changed by the calling
+            of its public methods, then your tool is not thread safe.  The
+            only thread-safe tools are those that maintain no state or are
+            otherwise immutable (e.g. return new, copied instances w/changed state 
+            and leave original unchanged).  If your tool is not thread-safe,
+            you should seriously consider <a href="#Annotations">using a
+            scope-limiting annotation</a> to prevent such problems.
+            </p>
+            <p>
+            Thread-safety is, of course, most important if your tool is meant to
+            be used in "application" or "session" scoped toolboxes for web
+            applications or any other multi-threaded application.  Allowing
+            access to non-thread-safe tools in those scopes can lead to 
+            all sorts of unpleasant problems. Please note that sometimes
+            request scope isn't safe either! if you #parse subtemplates
+            or are otherwise composing your page of separate pieces (e.g. Tiles)
+            that may not know what each other are doing at any one time.
+            </p>
+            <p>
+            <a href="javadoc/org/apache/velocity/tools/generic/AbstractLockConfig.html">AbstractLockConfig</a>
+            and its subclasses can help you have safely configurable tools
+            in any scope.  They do this by only allowing the public
+            <code>configure(Map)</code> method to be called once.  All other
+            configuration methods should then be declared protected and the
+            tool cannot be re-configured by a template.  This technique may,
+            in the future, be changed to allow you to replace the configure(Map) method
+            with a constructor that takes a Map of configuration properties,
+            but for various reasons, this is not currently the case.
+            </p>
+            <p>
+            As a final note here, if you really have good reason to use a
+            mutable, non-thread-safe application or
+            session scoped tool, tool path restrictions can help you limit
+            possible damage here.  Of course, this is something done purely at
+            the <a href="config.html">configuration</a> level and cannot
+            be currently defined by the tool itself.
+            </p>
+        </subsection>
+        <subsection name="Be Natural">
+            <todo>
+                talk about using "subtools" for a 
+                <a href="http://www.martinfowler.com/bliki/FluentInterface.html">fluent API</a>.
+            </todo>
+            <p>
+            Here's a few examples:
+            <ul>
+            <li>
+                <a href="javadoc/org/apache/velocity/tools/generic/ResourceTool.html">ResourceTool</a>
+                uses "subs" to allow you to type <code>$text.org.com.Foo</code> instead of
+                <code>$text.get('org.com.Foo')</code> or worse, something very java-ish like
+                <code>$text.getResourceFromBundle('messages.properties', 'org.com.Foo')</code>
+            </li>
+            <li>
+                <a href="javadoc/org/apache/velocity/tools/view/LinkTool.html">LinkTool</a>
+            </li>
+            <li>
+                <a href="javadoc/org/apache/velocity/tools/generic/ClassTool.html">ClassTool</a>
+            </li>
+            <li>
+                <a href="javadoc/org/apache/velocity/tools/struts/MessageTool.html">MessageTool</a>
+            </li>
+            </ul>
+            and more...
+            </p>
+        </subsection>
     </section>
 
     </body>

Modified: velocity/tools/trunk/xdocs/frameworks.xml
URL: http://svn.apache.org/viewvc/velocity/tools/trunk/xdocs/frameworks.xml?rev=660766&r1=660765&r2=660766&view=diff
==============================================================================
--- velocity/tools/trunk/xdocs/frameworks.xml (original)
+++ velocity/tools/trunk/xdocs/frameworks.xml Tue May 27 17:40:38 2008
@@ -28,10 +28,16 @@
 
     <body>
     <section name="Overview">
-        <p class="note">
-            This page is quite unfinished.
-            <a href="index.html#Contribution">Help is welcome!</a>
-        </p>
+        <todo>
+            <ul>
+            <li>Finish this page,</li>
+            <li>add a TOC for it,</li>
+            <li>incorporate the instructions and code for
+            integrating Tools 2 that are laid out in
+            <a href="http://velocity.markmail.org/search/?q=subject%3A%22upgrading%22#query:subject%3Aupgrading%20order%3Adate-forward+page:3+mid:pw56jxgsudhwwnnd+state:results">this email thread</a>,</li>
+            <li>and perhaps link to some examples.</li>
+            </ul>
+        </todo>
     </section>
     <section name="Integration Via VelocityView">
         <subsection name="Configuring">
@@ -56,40 +62,41 @@
                 <code>org.apache.velocity.tools.view.velocity.properties</code>.
                 </dd>
             </dl>
-            <p>
-            TODO: talk about deprecationSupportMode
-            </p>
+            <todo>talk about deprecationSupportMode</todo>
         </subsection>
         <subsection name="Retrieving">
-            <p>
-            TODO: finish this
-            </p>
+            <todo>talk about ServletUtils and constructors</todo>
         </subsection>
         <subsection name="Sharing">
-            <p>
-            TODO: finish this
-            </p>
+            <todo>
+                talk about motives, servlets, tags, filters
+                and org.apache.velocity.tools.shared.config
+            </todo>
         </subsection>
         <subsection name="Using">
-            <p>
-            TODO: finish this
-            </p>
+            <todo>discuss basic functions, config options, etc</todo>
         </subsection>
     </section>
     <section name="Other Ways to Integrate VelocityTools">
-        <subsection name="Direct Use Of Tools">
-            <p>
-            TODO: finish this
-            </p>
-        </subsection>
         <subsection name="ToolboxFactory">
+            <todo>discuss lifecycle, configuration, and use</todo>
+        </subsection>
+        <subsection name="Standalone Use" href="standalone.html">
             <p>
-            TODO: finish this
+            The so-called "standalone" methods of tool use
+            developed from a desire to
+            <a href="standalone.html#Just_Use_Them!">use tools directly</a>,
+            particularly the GenericTools which had no servlet
+            dependencies.  However, now many VelocityView tools
+            can also be used "standalone" with varying degrees
+            of effort and no need to create any VelocityView instances.
+            Most of the time, you just treat them like any other
+            POJO--create an instance, provide any need values/objects
+            and use it.
             </p>
-        </subsection>
-        <subsection name="ToolManager">
             <p>
-            TODO: finish this
+            If you want a little more help with things, consider using a
+            <a href="standalone.html#ToolManager">ToolManager</a>.
             </p>
         </subsection>
     </section>