dobbs       2002/05/31 16:41:08

  Modified:    xdocs    howtos.xml
  Added:       xdocs/howto intake-howto.xml
  Log:
  HOWTO for Intake courtesy of Daniel Kha dantestATyorku.ca
  
  Revision  Changes    Path
  1.3       +1 -0      jakarta-turbine-2/xdocs/howtos.xml
  
  Index: howtos.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-2/xdocs/howtos.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- howtos.xml        3 Apr 2002 02:47:27 -0000       1.2
  +++ howtos.xml        31 May 2002 23:41:08 -0000      1.3
  @@ -17,6 +17,7 @@
           <li><a href="howto/extend-user-howto.html">Extend User Howto</a></li>
           <li><a href="howto/jboss-howto.html">JBoss Howto</a></li>
           <li><a href="howto/jsp-howto.html">JSP Howto</a></li>
  +        <li><a href="howto/intake-howto.html">Intake Howto</a></li>
           <li><a href="howto/mssql-howto.html">MS SQL Server Howto</a></li>
           <li><a href="howto/oracle-howto.html">Oracle 8i Howto</a></li>
           <li><a href="howto/peers-howto.html">Peers Howto</a></li>
  
  
  
  1.1                  jakarta-turbine-2/xdocs/howto/intake-howto.xml
  
  Index: intake-howto.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
      <properties>
          <title>"Simple" Intake How-to for Turbine 2.1</title>
          <author email="[EMAIL PROTECTED]">Daniel Kha</author>
      </properties>
  
      <body>
          <section name="Introduction">
              <p>
                  First of all I'd like to note that this document is based on my
                  experience in using Intake for Turbine 2.1.  I've tried to make
                  it as correct as possible but I don't guarantee anything.  This
                  has been written as a guide for a new Intake user and assumes
                  some familiarity with Turbine 2.1.
              </p>
              <p>
                  To use intake, the following steps are required:
  
                  <ol>
                      <li>Create your turbine template with a form.</li>
                      <li>Create the intake.xml file.</li>
                      <li>Create a business object to represent the intake group
                          we are working with (this is optional).</li>
                      <li>Create the Turbine Action to handle the form
                          submission.</li>
                  </ol>
              </p>
          </section>
  
          <section name="Step 1: Create your turbine template with a form"> 
              <p>
                  The first thing to do is the create the form in your template
                  (e.g. a velocity template file, a .vm file).  Just create the
                  skeleton structure and don't worry about the field names and
                  values yet.  Note that field names will have to match the names
                  specified in the intake.xml file.  Actually you can do the
                  opposite (name the fields here first and match them in the
                  intake.xml file) if you wish, but this guide will do it the
                  former way.
              </p>
              <p>
                  Now add the following lines above the code for your form and
                  modify it to match the group and field names in your intake.xml
                  file (perhaps you can come back to do this step after you've
                  done your intake.xml file).  Here is an example in a Velocity
                  template for a "login form":
              </p>
              <source><![CDATA[
  #set($loginGroup = $intake.LoginGroup.Default) 
              ]]></source>
              <p/>
              <p>
                  What this does is to set a Velocity variable called $loginGroup
                  to a default group object specified by intake.xml.  The $intake
                  variable is the Turbine Pull Tool instance (IntakeTool).  The
                  "LoginGroup" is the name of the group as specified in the
                  intake.xml file (names must match, and this is not the group's
                  key attribute.).  The "Default" part obtains a generic default
                  intake group object. Or in other words, this resolves to
                  IntakeTool.get(String groupName) with the groupName being
                  "LoginGroup".  Also, you can re-write the statement as
                  $intake.get("LoginGroup").getDefault() in your template.
              </p>
              <p>
                  Or if you would like to map the intake group to a business
                  object (for whatever purpose) then you can do this (read on
                  for more info on what is required to do this in intake.xml and
                  the corresponding Turbine Action class):
              </p>
              <source><![CDATA[
  #set($loginGroup = $intake.LoginGroup.mapTo($mytool.getInstanceLoginForm()))
              ]]></source>
              <p/>
              <p>
                  What this does is to set a Velocity variable called $loginGroup
                  to an instance of the LoginForm business object (and if the
                  returned object has values in its fields and appropriate
                  "getter" methods then this would prepopulate the intake group
                  with the values.  A good usage example of this is when you
                  would like to prepopulate the form with values from the
                  database and want to use intake to validate the form).  It
                  makes use of a custom tool placed into the Velocity context as
                  "$mytool" (you can make your own tool to instantiate an instance
                  of your business object similar to this example).
              </p>
              <p>
                  So, depending on the method you use above, the corresponding
                  Turbine Action code will need to "cooperate" accordingly.
                  We'll discuss this later in step 4.
              </p>
              <p>
                  Near the end of the form (before you close the "form" tag)
                  include the following line:
              </p>
              <source><![CDATA[
  $intake.declareGroups()
              ]]></source>
              <p/>
              <p>
                  What this does is to fill in hidden form fields into the form
                  for use by intake.
              </p>
              <p>
                  In order to use Turbine's Action event system, the submit buttons
                  must adhere to the naming specification defined by
                  <a 
href="http://jakarta.apache.org/turbine/turbine-2/howto/action-event-howto.html";>
                  Turbine's Action event system</a>.
              </p>
  
              <subsection name="*** IMPORTANT NOTE ***">
                  <p>
                      If you use
                      $link.setAction('SomeAction').setPage('NextTemplate.vm')
                      in your form's action attribute like this:
                  </p>
                  <source><![CDATA[
  <form name="myForm" method="POST"
        action="$link.setAction('LoginAction').setPage('NextTemplate.vm')">
      ...
  </form>
                  ]]></source>
                  <p/>
                  <p>
                      then the form validation won't appear to work (i.e. the user
                      will see the NextTemplate.vm file instead of the form they
                      were trying to fill out which failed validation).  To work
                      around this problem, you can omit the setPage('...') part
                      in your form's action attribute and then have your action
                      route the user to the next template on validation success
                      OR somehow detect the current form the user is at and if
                      the validation fails, override the next template to the
                      current template (which is really just overriding the
                      setPage() part in the template file specified by the web
                      designer).
                  </p>
              </subsection>
          </section>
  
          <section name="Step 2: Create the intake.xml file"> 
              <p>
                  The intake.xml file specifies the validation rules required to
                  be satisfied in order for the form to be accepted.  The file has
                  a "root" XML element of "input-data" and in that would be
                  "group" elements.
              </p>
              <p>
                  Here is an example of the element (with no other sub-elements):
              </p>
              <source><![CDATA[
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <!DOCTYPE input-data SYSTEM
             "http://jakarta.apache.org/turbine/dtd/intake.dtd";>
  <input-data basePackage="ca.yorku.devteam.inca.clients.skeleton.">
      ...group elements goes here...
  </input-data>
              ]]></source>
              <p/>
              <p>
                  Notice the basePackage attribute (optional) points to the
                  skeleton package with an extra period at the end.  This
                  attribute specifies the package that contains the java objects
                  the "group" and "field" elements can optionally map to.
                  The trailing period is REQUIRED.
              </p>
  
              <subsection name="&lt;group&gt; elements">
                  <p>
                      Each group element represents a collection of field information 
you'd like to
                      validate in your form.  For example, on a login page you would 
have a form for
                      the user to input their username and password, and as well as a 
login button.
                      This entire form would be grouped as a group in the intake.xml 
file.
                  </p>
                  <p>
                      Here is an example of a group with no other elements (not useful 
yet):
                  </p>
                  <source><![CDATA[
  <group name="LoginGroup" key="loginGroupKey" mapToObject="LoginForm">
      ...field elements goes here...
  </group>
                  ]]></source>
                  <p/>
                  <p>
                      A group element can have the following attributes:
  
                      <ul>
                          <li>"name" attribute
                              <ul>
                                  <li>
                                      the name of the group, is required, and must
                                      be unique across the entire intake.xml file.
                                  </li>
                              </ul>
                          </li>
                      </ul>
  
                      <ul>
                          <li>"key" attribute
                              <ul>
                                  <li>
                                      the key of the group, is required, and must
                                      be unique across the entire intake.xml file.
                                  </li>
                              </ul>
                          </li>
                      </ul>
  
                      <ul>
                          <li>"mapToObject" attribute
                              <ul>
                                  <li>
                                      optional, used if you want to map the form
                                      to a business object. Note that the field
                                      names specified later by the "field" element
                                      in the group should match the field names of
                                      the business object with appropriate get/set
                                      methods.  See the "field" tag examples to
                                      find how to override this default behaviour.
                                  </li>
                              </ul>
                          </li>
                      </ul>
                  </p>
                  <p>
                      For a complete list of valid attributes of the group
                      element, please see the
                      <a 
href="http://jakarta.apache.org/turbine/turbine-2/services/intake-service.html";>
                      intake-service document</a> on the Turbine web site.
                  </p>
              </subsection>
  
              <subsection name="&lt;field&gt; elements">
                  <p>
                      Each group element can contain any number of "field"
                      elements.  Each field element will correspond to a field in
                      the form.  The name and key of each field will be used in
                      the form code in the template so make sure the names and
                      keys match in both files (intake.xml and the template file).
                  </p>
                  <p>
                      Here is an example of a field with no other elements (not
                      too useful yet):
                  </p>
                  <source><![CDATA[
  <field name="Username" key="loginUsernameKey" type="String"
          mapToProperty="Username">
      ...rule elements goes here...
  </field>
                  ]]></source>
                  <p/>
                  <p>
                      A field element can have the following attributes:
  
                      <ul>
                          <li>"name" attribute
                              <ul>
                                  <li>
                                      the name of the field, is required, and must
                                      be unique across the entire group element.
                                  </li>
                              </ul>
                          </li>
                      </ul>
  
                      <ul>
                          <li>"key" attribute
                              <ul>
                                  <li>
                                      the key of the field, is required, and must
                                      be unique across the entire group element.
                                  </li>
                              </ul>
                          </li>
                      </ul>
  
                      <ul>
                          <li>"type" attribute
                              <ul>
                                  <li>
                                      required, the type of the field so that
                                      intake will know what to expect.  Valid
                                      types I know of are: String, Integer (I
                                      believe these map to the corresponding Java
                                      types).  Please see the intake.dtd for the
                                      allowed values.
                                  </li>
                              </ul>
                          </li>
                      </ul>
  
                      <ul>
                          <li>"mapToProperty" attribute
                              <ul>
                                  <li>
                                      optional, used if you want to map the form
                                      to a business object.  Note that the field
                                      names specified in this "field" element
                                      should match the field name of the business
                                      object with appropriate get/set methods.
                                  </li>
                              </ul>
                          </li>
                      </ul>
                  </p>
                  <p>
                      For a complete list of valid attributes of the field
                      element, please see the
                      <a 
href="http://jakarta.apache.org/turbine/turbine-2/services/intake-service.html";>
                      intake-service document</a> on the Turbine web site.
                  </p>
              </subsection>
  
              <subsection name="&lt;rule&gt; elements">
                  <p>
                      In each field element, you can have rules defined.  The
                      supported rule elements for Intake in Turbine 2.1 are:
                  </p>
                  <source><![CDATA[
  <rule name="required" value="true">Error message for required failed</rule>
  <rule name="minLength" value="4">Error message for required min length failed</rule>
  <rule name="maxLength" value="9">Error message for required max length failed</rule>
  <rule name="mask" value="^[0-9]+$">Error message for regular expression failed</rule>
                  ]]></source>
                  <p/>
                  <p>
                      For more info on the supported rules, please see the
                      <a 
href="http://jakarta.apache.org/turbine/turbine-2/services/intake-service.html";>
                      intake-service document</a> on the Turbine web site:
                  </p>
              </subsection>
          </section>
  
          <section name="Step 3: Create a business object to represent the intake 
group we are working with (this is optional)."> 
              <p>
                  The business object is basically a Java class that has get and
                  set methods for each of the object's fields, and these get and
                  set method names should match the field names specified in the
                  intake.xml file (whether we stay with the default behaviour of
                  matching the field names in intake.xml and the business object
                  or we use the mapToProperty attribute in the "field" element).
                  Note it is required to use the mapToObject property in the group
                  element to use this feature.
              </p>
              <p>
                  The business object also has to implement the
                  org.apache.turbine.om.Retrievable interface.  The Retrievable
                  was designed to work with a database so the methods 
                  get/setQueryKey doesn't make much sense if your business object
                  isn't based on a database model.  For my use, I just force the
                  key to be "_0" which is the default key used by Intake (as of
                  Turbine 2.1).  You could, of course, implement it as a normal
                  data field to allow the template to set the query key and then
                  in the Action to get the query key.  But then you'll have to
                  keep track of the key you use in both the template file and
                  Action class (the benefit would be that you'll be able to use
                  more than 1 business object in the same template if you get/set
                  the different query keys).
              </p>
              <p>
                  Here is an example of how to use the setQueryKey() and
                  getQueryKey() methods of the business object that implements
                  the Retrievable interface:
              </p>
              <p>
                  In the template file, e.g. myform.vm:
              </p>
              <source><![CDATA[
  #set($loginForm = $mytool.getLoginFormInstance())
  $loginForm.setQueryKey("abc")
  #set($loginGroup = $intake.LoginGroup.mapTo($loginForm))
              ]]></source>
              <p/>
              <p>
                  In the Action class:
              </p>
              <source><![CDATA[
  // This key has to match the one in the template
  String key = "abc";
  Group group = intake.get("LoginGroup", key);
              ]]></source>
              <p/>
          </section>
  
          <section name="Step 4: Create the Turbine Action to handle the form 
submission."> 
              <p>
                  Depending on the method you use, the code in the action will
                  need to obtain the corresponding group object from intake.  The
                  following examples will demonstrate the ideas.
              </p>
              <p>
                  Here is an example the code in a Turbine Action, using intake
                  without mapping to a business object (vanilla method):
              </p>
              <source><![CDATA[
  /**
   * Performs user login
   */
  public void doLogin(RunData data, Context context)
          throws Exception {
      // Get intake group
      IntakeTool intake =
              (IntakeTool)context.get("intake");
  
      // Notice how this gets the group named "LoginGroup" as defined in
      // the intake.xml file, and gets it using the default key
      // IntakeTool.DEFAULT_KEY (which is "_0").
      Group group = intake.get("LoginGroup", IntakeTool.DEFAULT_KEY);
  
      // Check if group fields are valid and if they are not, then return.
      // Intake will handle the validation error and display the
      // corresponding error messages to the user but if you use the setPage()
      // mechanism to get the "next template" then you must now set the
      // template to be the same one as the user was filling out.  Otherwise
      // the user will just see the next template.  See the "important note"
      // in step 1.
      if (!group.isAllValid()) {
          Log.debug("Group elements INVALID");
          setTemplate(data, "Login.vm");
          return;
      } else {
          // If all is validated then you can set the next template and/or
          // continue processing...it's up to you.  You can also use
          // setPage() in the template file to set the next template to show
          // on successful validation.
          setTemplate(data, "LoginSuccess.vm");
      }
  
      // This gets the value of the "Username" field from the group object
      String username = (String)group.get("Username").getValue();
      String password = (String)group.get("Password").getValue();
  
      // Now you will be able to use the username and password variable in
      // the rest of the Turbine Action.
      ...
  }
              ]]></source>
              <p/>
              <p>
                  Here is example code in a Turbine Action, using the intake
                  group's default mapToObject setting (this is the same whether
                  or not you use the field's mapToProperty attribute):
              </p>
              <source><![CDATA[
  /**
   * Performs user login
   */
  public void doLogin(RunData data, Context context)
          throws Exception {
      // Get intake group
      IntakeTool intake =
              (IntakeTool)context.get("intake");
      Group group = intake.get("LoginGroup", IntakeTool.DEFAULT_KEY);
  
      // Check if group fields are valid and if they are not, then return.
      // Intake will handle the validation error and display the
      // corresponding error messages to the user but if you use the setPage()
      // mechanism to get the "next template" then you must now set the
      // template to be the same one as the user was filling out.  Otherwise
      // the user will just see the next template.  See the "important note"
      // in step 1.
      if (!group.isAllValid()) {
          Log.debug("Group elements INVALID");
          setTemplate(data, "Login.vm");
          return;
      } else {
          // If all is validated then you can set the next template and/or
          // continue processing...it's up to you.  You can also use
          // setPage() in the template file to set the next template to show
          // on successful validation.
          setTemplate(data, "LoginSuccess.vm");
      }
  
      // Instaniate a business object that represents the form
      LoginForm loginForm = new LoginForm();
  
      // Set the properties of the form given the field data in the group
      // (i.e. populate the business object)
      group.setProperties(loginForm);
  
      // Now the business object is populated accordingly.  You can use it
      // for whatever purpose in the rest of the Turbine Action.
      ...
  }
              ]]></source>
              <p/>
          </section>
      </body>
  </document>
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to