<?xml version="1.0" encoding="UTF-8"?>
<!--
   Copyright 2004 The Apache Software Foundation
  
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
  
       http://www.apache.org/licenses/LICENSE-2.0
  
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-->
<!-- $Id$ -->
<!DOCTYPE faqs PUBLIC "-//APACHE//DTD FAQ V1.2//EN" "dtd/faq-v12.dtd">

<faqs title="Jakarta Tapestry - FAQs">


    <part id="general">
        <title>General Tapestry Information</title>

        <faq>
            <question>How does Tapestry compare to other frameworks?</question>
            <answer>
                <p>
Tapestry is very much unlike most other frameworks in that it doesn't use
code generation; instead it uses a true component object model based
on JavaBeans properties and strong specifications.  This gives Tapestry a huge
amount of flexibility and enables dynamic runtime inspection of the application
with the Tapestry Inspector (a mini-application that can be built into any Tapestry
application).
                </p>

                <p>In addition, Tapestry applications require 
far less Java coding and are far more robust than equivalent 
applications developed with other popular frameworks. This is 
because the Tapestry framework takes responsibility for many 
important tasks, such as maintaining server-side state and 
dispatching incoming requests to appropriate objects and methods.</p>
                <p>The many new features of release 3.0 mean that Tapestry is not 
only the most powerful web application framework available, it is 
also the fastest and easiest to adopt, regardless of whether your 
background is Java, Perl, XML or PHP!</p>
            </answer>
        </faq>


        <faq>
            <question>How is the performance of Tapestry?</question>
            <answer>
                <p>		
		My own testing, documented in the Sept. 2001 issue of the Java Report,
	agrees with other testing (documented in the Tapestry discussion forums):
	Although straight JSPs have a slight edge in demo applications, in
	real applications with a database or application server backend, the performance
	curves for equivalent Tapestry and JSP applications are identical.
                </p>

                <p>Don't think about the performance of 
            Tapestry; think about the performance of your Java developers.</p>

            </answer>
        </faq>

        <faq>
            <question>Is Tapestry a JSP tag library?</question>

            <answer>
                <p>	Tapestry is
                    <em>not</em> a JSP tag library; Tapestry builds on the 
            servlet API, but doesn't use JSPs in any way.&nbsp; It uses it own 
            HTML template format and its own rendering engine.
                </p>


                <p>
	Starting with release 3.0, Tapestry includes a simple JSP tag library
	to allow JSP pages to create links to Tapestry pages.	
                </p>
            </answer>
        </faq>

        <faq>
            <question>What does it cost?</question>

            <answer>
                <p>		
		Tapestry is open source and free.  It is licensed
	under the Apache Software License, which allows
	it to be used even inside proprietary software.
                </p>
            </answer>
        </faq>

        <faq>
            <question>Is there a WYSIWYG editor for Tapestry, or an IDE plugin?</question>

            <answer>
                <p>
		
		Currently, no WYSIWYG editor is available for Tapestry; however, the design of Tapestry
	allows existing editors to work reasonably well (Tapestry additions to the HTML markup
	are virtually invisible to a WYSIWYG editor).</p>

                <p>
                    <link href="http://sf.net/projects/spindle">Spindle</link>
is a Tapestry plugin 
	for the excellent open-source
                    <link href="http://www.eclipse.org">Eclipse</link> IDE. It adds wizards and editors 
            for creating Tapestry applications, pages and components.
                </p>
            </answer>
        </faq>

        <faq>
            <question>Does Tapestry work with other other application servers
		 besides JBoss?</question>
            <answer>

                <p>Of course!
                    <link href="http://www.jboss.org">JBoss</link> is free and convienient for the 
            turn-key demonstrations. You can download Tapestry and JBoss 
            and have a real J2EE application running in about a minute! 
            The scripts that configure JBoss are sensitive to the particular 
            release of JBoss, it must be release 3.0.6.
                </p>
                <p>However, Tapestry 
            applications are 100% container agnostic ... Tapestry doesn't care 
            what servlet container it is used with and does not even require an EJB container.</p>
            </answer>
        </faq>

    </part>

    <part id="technical">
        <title>Technical Questions</title>

        <faq>
            <question>
                How do I integrate a Tapestry application with J2EE declarative security/JAAS?
            </question>
            <answer>
                <p>In web.xml:</p>


                <p>add an additional servlet mapping for your tapestry application to /admin, and add the following:</p>

                <source><![CDATA[
<security-constraint>
 <web-resource-collection>
  <url-pattern>/admin/*</url-pattern>
 </web-resource-collection>
 <auth-constraint>
   <role-name>ADMIN</role-name>
 </auth-constraint>
</security-constraint>
                    ]]></source>
                <p>In your base class for protected pages:</p>


                <source><![CDATA[
public void validate(IRequestCycle cycle) throws RequestCycleException {

  boolean isAdmin = getRequestCycle().getRequestContext().getRequest().isUserInRole("ADMIN");
  if (!isAdmin) {
    // not in right role
    throw new PageRedirectException.......
  }

}
                ]]></source>

                <p>you can have a number of mappings for the same app-servlet to
                 different URIs, that way you can rely a bit more on the
                 declarative security.. not perfect, but works.. :)</p>


                <p>ViktorSzathmary</p>

            </answer>
        </faq>
        <faq>
            <question>
            How do I Write Components?
            </question>
            <answer>


                <p>1.</p>


                <p>Retrieving bound properties : When writting a component,
                 you often require various properties to be supplied by
                 the component user. At some point during rendering,
                 you will want to use the value of this property.</p>

                <p>You can do this by accessing the Binding. Assume we
                 have a component with one property called 'values'.
                 Our component will use this list in its preRenderCommponent()
                 method to setup some model, for use elsewhere.</p>


                <source><![CDATA[
.... if(getValues() == null) {

  IBinding binding = getBindings("values"); if(binding.getObject() == null) {

      throw new RequestCycleException("The value for 'values' cannot be null", this);

  } setValues((List)values.getObject());

}
                ]]></source>
                <p>The binding itself will ensure that the object value is
                the correct type (assuming of course, it's been setup right).</p>

                <p>2.</p>


                <p>Performing Lazy Instantiation of state based upon component
                 properties : In some cases, the output of a component may be
                 based upon the state of some other property of the same
                 component. For example, imagine a form where the user can
                 choose the type of product to view. When they choose a
                 product, the form makes a query to the database for
                 products matching this type, and reshows the list
                 on the same page. (the list would be included outside
                 of the form element itself).</p>

                <p>Lets assume that the page object exposes it's products
                via a getProductModel() - which is an instance of
                IPropertySelectionModel.</p>

                <p>We will also assume that the remainder of the page has the
                 other components necessary to render correct HTML, using the
                 value supplied by the getProductModel() result.</p>

                <p>
                Here, it is helpful to know when in the rendering process
                you can rely on the value of selectedProduct to be set correctly,
                so that you can instantiate a ProductModel based on the provided
                value, for use in the form rendering.
                The best place to setup state is in the preRenderComponent()
                method. This is called by Tapestry just before it renders any component,
                but AFTER it has set component properties.
                So, we might write:
                </p>

                <source><![CDATA[
protected void preRenderComponent() {

  String selected = getSelectedProduct();
  List products = getMatchingProducts(selectedProduct);
  productModel = new ProductModel(products);
  .. other initialization code ...

}
]]></source>

            </answer>
        </faq>
        <faq>
            <question>
                @Script - Why is it needed and how does it work?
            </question>
            <answer>
                <p>IMO, the script framework is an effective means to bundle
                 scripts in components. It provides scripts with the advantages
                 of components. It can now be reused like a component and not
                 have to worry about renaming field names or the wiring between
                 the fields and the scripts. You just declare the component
                 and you are good to go. It certainly is another layer of
                 abstraction that one will have to learn but once you have
                 learned it, it is very powerful. And honestly there is not
                 much to it.</p>

                <p>The script framework is mandated by the fact that form
                 element/field names are automatically generated by the framework. And so
                 you write your script in XML and use variables for these names and let the
                 framework provide the correct names during runtime. Going further, you may
                 also ask the framework to provide other objects that would help in creating
                 your script. For example...</p>


                <source><![CDATA[
<input-symbol key="select"
    class="org.apache.tapestry.form.PropertySelection"
    required="yes"/>
                ]]></source>

                <p>This defines an input variable "select" of type
                 "org.apache.tapestry.form.PropertySelection". All such
                 variables/symbols passed in to the script is stored in
                 a symbol map. And now you can use the form select list
                 name by using an ant style syntax like ${select.name}.
                 The expression within "${}" is an OGNL expression and is
                 evaluated with respect to the symbol map. You may also
                 define your own symbols/variables using &lt;let...&gt;
                 like...
                </p>

                <source><![CDATA[
<let key="formObj">

    document.${select.form.name}

</let>
<let key="selectObj">

    ${formObj}.${select.name}

</let>
                ]]></source>

                <p>These variables/symbols are stored in the symbol map also. So
                 now if you want to set the value of the form select list all
                 you do is say ${formObj}.${selectObj}.value = 'whatever'; this
                 would be equivalent to <code>document.myForm.mySelect.value = 'whatever';</code>
                 where <code>myForm</code>
                  is the form name and mySelect is the select list name.</p>


                <p>&lt;input-symbol...&gt;s are like method parameters and &lt;let...&gt;s
                 are like instance variables. Typically you would pass values
                 to the &lt;input-symbol...&gt;s via the Script component like...</p>


                <source><![CDATA[
<component id="myScript" type="Script">

    <static-binding name="script" value="ScriptSpecificationName.script"/>
    <binding name="select" expression="components.somePropertySelection"/>

</component>
                ]]></source>

                <p>The actual scripts are defined in one of the two sections
                 of the script specification, &lt;body...&gt; or &lt;initialization...&gt;,
                 depending on when you want the script to execute. If you want the script to
                 execute on load of the page, then you define it in the
                 &lt;initialization...&gt;, if you want it to execute on any
                 other event, define it in the &lt;body...&gt; section of the specification.
                 For example...</p>

                <source><![CDATA[
<body>

    function onChangeList(listObj)
    {

        alert(listObj.value);

    }

</body>

<initialization>

    ${selectObj}.onchange = function(e)
    {

        onChangeList(${selectObj});

    }

</initialization>
                ]]></source>

                <p>As you can see in the rendered page all scripts are aggregated at the top
                 of the page body, there are no more scripts all over the page. Even event
                 handlers are attached to form objects in the initialization block.</p>


                <p>One more thing to remember, scripts being components, and components by
                 nature being independent of its environment, will render the script in the
                 page once for every ocurrance of the component. If you want the body of the
                 script to be rendered only once no matter how many times the component is used,
                 just wrap the body in a &lt;unique&gt; tag like...</p>


                <source><![CDATA[
<body>
<unique>

    function onChangeList(listObj)
    {

        alert(listObj.value);

    }

</unique>
</body>
                ]]></source>

                <p>That's all there is to it!</p>


                <p>* HarishKrishnaswamy</p>


            </answer>
        </faq>
        <faq>
            <question>
                cycle.activate() does not seem to alter the URL. Is there any
                alternative that will alter the URL to point to the correct page?
            </question>
            <answer>
                You would need to throw a RedirectException with the new URL;
                this sends an HTTP redirect to the client.
            </answer>
        </faq>
        <faq>
            <question>
                How do I do page navigation like struts?
            </question>
            <answer>
                <p>Usage page properties:</p>


                <source><![CDATA[
Page1.page
<page-specification class="xyz.Action">
...
        <property name="success" value="Home" />
        <property name="error" value="Error" />


</page-specification>


Page2.page
<page-specification class="xyz.Action">
...
        <property name="success" value="Home2" />
        <property name="error" value="Error2" />

</page-specification>

xyz.Action.java
...
public void submitListener(IRequestCycle cycle)
{
    if (success)
        cycle.activate(getSpecification().getProperty("success"));

    if (error)
        cycle.activate(getSpecification().getProperty("error"));
}
]]></source>

                <p>-- Tip from Harish</p>

            </answer>
        </faq>
        <faq>
            <question>
                How do I make a link popup a new window?
            </question>
            <answer>
                Use the contrib:PopupLink component.
            </answer>
        </faq>

        <faq>
            <question>
                How do I stream a file to the user from tapestry?
            </question>
            <answer>
                <p>Make a method like the following a a listener, such as from a DirectLink or whatever.</p>

                <p>(The Document is just a class that holds the file information you want to send to the user.)</p>

                <source><![CDATA[
public void downloadAction(IRequestCycle cycle)
{
    try
    {
        HttpServletResponse response =
        cycle.getRequestContext().getResponse();


        byte[] data = new byte[1024];
        FileInputStream in = document.getFileInputstream();


        response.setHeader("Content-disposition",
          "inline; filename=" +
           document.getFileName());
        response.setContentType(document.getMimeType());
        response.setContentLength(new Long(document.getSize()).intValue());
        ServletOutputStream out = response.getOutputStream();

        while (in.read(data) > -1)
        {
            out.write(data);
        }
        in.close();
        response.flushBuffer();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}
                ]]></source>


            </answer>
        </faq>

        <faq>
            <question>
                I need to calculate a URL to jump to a particular page. How do I do this?
            </question>
            <answer>
                <p>The best bet is to use the external service. This lets you directly
            invoke a page and pass objects as parameters. The page you
            want to jump to will need to implement IExternalPage. To calculate
            the URL you have to use something like this:</p>


                <source><![CDATA[
cycle.getEngine()
    .getService( Tapestry.EXTERNAL_SERVICE )
    .getLink( cycle, cycle.getPage(), new Object[]{
        "MyPageName",
        param1,
        param2} )
    .getURL()
                ]]></source>
            </answer>
        </faq>

        <faq>
            <question>
                I have a form with a submit button. On the form and the submit
                button are two separate listeners. Which is invoked first?
            </question>
            <answer>
                <p>The button's listener should get invoked when the form
                encounters your button during the rewind. the form's
                submitListener should get invoked after the form has completed
                its rewind, and thus after all other listeners have been
                invoked. note - this can mean that the listener for a button can be invoked
                BEFORE the form has 'submitted' all its values - it depends
                where your input fields are relative to your button.</p>
            </answer>
        </faq>

        <faq>
            <question>
                I'd like to be able attach my own client-side javascript
                handling on the form submit. What's the best way to do this?
            </question>
            <answer>
                <p>You can add event handler during component rendering:</p>

                <source><![CDATA[
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle){
    ...
    yourFormComponent.addEventHandler(FormEventType.SUBMIT, "javaScriptValidatingFunctionName");
    ...
}
                ]]></source>

                <p>
                    <code>org.apache.tapestry.contrib.palette.Palette</code> can be used for detailed example.
                </p>

            </answer>
        </faq>

        <faq>
            <question>
                What's the lifecycle of a form submit?
            </question>
            <answer>
                <p>Events will trigger in the following order:</p>


                <source><![CDATA[
initialize()
pageBeginRender()
formListenerMethod()
pageBeginRender()
                ]]></source>

                <p>The form "rewind" cycle is nothing more than a render cycle
where the output is buffered and scrapped rather than written
to the servlet output stream. The second pageBeginRender() is
triggered during the actual page rendering. You can use
requestCycle.isRewinding() to distinguish between these
two render cycles.</p>

            </answer>
        </faq>

        <faq>
            <question>
                Can I use the same component multiple times in one template?
            </question>
            <answer>
                <p>No - but you can copy the definition of a component pretty easily.</p>

                <source><![CDATA[
<component id="valueInsert" type="Insert" >
   <binding name="value" expression="getValueAt( rowIndex, columnIndex )" />
</component>

<component id="valueInsert1" copy-of="valueInsert"/>
<component id="valueInsert2" copy-of="valueInsert"/>
<component id="valueInsert3" copy-of="valueInsert"/>
<component id="valueInsert4" copy-of="valueInsert"/>
                ]]></source>
            </answer>
        </faq>

        <faq>
            <question>
                I have to restart my application to pick up changes to specifications and templates, how
                can I avoid this?
            </question>

            <answer>
                <p>

Start your servlet container with the JVM system parameter
                    <code>org.apache.tapestry.disable-caching</code> set to true, i.e.,
                    <code>-Dorg.apache.tapestry.disable-caching=true</code>.
                </p>

                <p>Tapestry will discard cached specifications
            and templates after each request. You application will run a bit
            slower, but changes to templates and specifications will show up
            immediately. This also tests that you are persisting server-side
            state correctly.</p>
            </answer>

        </faq>

        <faq>
            <question>What is "line precise error reporting"?</question>

            <answer>
                <p>
		Tapestry applications are built from templates and specifications.
		It's natural that when these templates and specifications are read, any syntax
		errors
		are reported, and the precise file and location is identified.
                </p>

                <p>
		Tapestry goes far beyond that!  It always relates runtime objects
		back to the corresponding files so that even runtime errors report the
		file and location.
                </p>


                <jump href="images/LinePrecise.png">
                    <figure src="images/LinePrecise_thumb.png" alt="Line Precise"/>
                </jump>
                <caption>	Tapestry exception report (click for larger image).</caption>

                <p>
		For example; say you bind a parameter of a component that expects
		a non-null value, but the value ends up being null anyway, due to
		a bug in your code or your specification.
	    Tapestry can't tell, until runtime,
		that you made a mistake ... but when it does, part of the exception report
		will be the line in the template or specification where you bound the component parameter.
		Zap!  You are sent right to the offending file to fix the problem.
                </p>


                <p>
		Other frameworks may report syntax errors when they parse their specifications, but
		after that, you are own your own: if you are lucky, you'll get a stack trace.  Good luck
		finding your error in that!  Tapestry gives you a wealth of information when unexpected
		exceptions occur, usually more than enough to pinpoint the problem
                    <em>without</em> having to restart the application inside a debugger.
                </p>
            </answer>
        </faq>
    </part>

    <part id="other-frameworks">
        <title>Other Frameworks</title>

        <faq>
            <question>How do I intergrate Tapestry with Spring?</question>

            <answer>

                <link href="http://www.springframework.org/">Spring</link> is a popular
		service framework. Colin Sampaleanu
		has written a
                <link href="http://www.springframework.org/docs/reference/view.html#view-tapestry">integration
		document</link> on using these two open-source frameworks together.

            </answer>

        </faq>

    </part>
</faqs>


