You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/02/04 20:01:20 UTC

svn commit: r618379 - in /tapestry/tapestry5/trunk: tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ tapestry-core/src/main/java/org/apache/tapestry/ tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ tapestry-core/src...

Author: hlship
Date: Mon Feb  4 11:01:18 2008
New Revision: 618379

URL: http://svn.apache.org/viewvc?rev=618379&view=rev
Log:
TAPESTRY-2076: Component report should break out as one class per page and include examples

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.xdoc
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_customized.png   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_simple.png   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_validation1.png   (with props)
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_validation2.png   (with props)
Modified:
    tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PrimaryKeyEncoder.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValueEncoder.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.xdoc
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/conf.apt

Modified: tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java?rev=618379&r1=618378&r2=618379&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java (original)
+++ tapestry/tapestry5/trunk/tapestry-component-report/src/main/java/org/apache/tapestry/mojo/ComponentReport.java Mon Feb  4 11:01:18 2008
@@ -52,7 +52,7 @@
     private static final String REFERENCE_DIR = "ref";
 
     private final static String[] PARAMETER_HEADERS = {"Name", "Type", "Flags", "Default", "Default Prefix",
-                                                       "Description"};
+            "Description"};
 
 
     /**
@@ -94,6 +94,12 @@
     private File generatedDocsDirectory;
 
     /**
+     * @parameter expression="${project.build.directory}/generated-site/resources"
+     * @required
+     */
+    private File generatedResourcesDirectory;
+
+    /**
      * Working directory for temporary files.
      *
      * @parameter default-value="target"
@@ -208,12 +214,12 @@
 
                 sink.listItem();
 
-                sink.link(className + ".html");
+                sink.link(toPath(className) + ".html");
 
                 sink.text(className);
                 sink.link_();
 
-                writeClassDescription(descriptions, refDir, docSearchPath, sink, className);
+                writeClassDescription(descriptions, refDir, docSearchPath, className);
 
 
                 sink.listItem_();
@@ -232,10 +238,19 @@
         }
     }
 
+    private String toPath(String className)
+    {
+        return className.replace('.', '/');
+    }
+
     private String extractSubpackage(String className)
     {
         int dotx = className.indexOf(".", rootPackage.length() + 1);
 
+        // For classes directly in the root package.
+
+        if (dotx < 1) return "";
+
         return className.substring(rootPackage.length() + 1, dotx);
     }
 
@@ -260,8 +275,17 @@
     }
 
     private void writeClassDescription(Map<String, ClassDescription> descriptions, File refDir,
-                                       List<File> docSearchPath, Sink sink, String className) throws Exception
+                                       List<File> docSearchPath, String className) throws Exception
     {
+
+        int dotx = className.lastIndexOf('.');
+        String packageName = className.substring(0, dotx);
+        File outputDir = new File(refDir, toPath(packageName));
+        outputDir.mkdirs();
+
+        File outputFile = new File(refDir, toPath(className) + ".xml");
+
+
         Element root = new Element("document");
 
         ClassDescription cd = descriptions.get(className);
@@ -297,9 +321,21 @@
 
         addChild(section, "p", cd.getDescription());
 
-        String javadocURL = String.format("../%s/%s.html", apidocs, className.replace('.', '/'));
 
-        addLink(addChild(section, "p"), javadocURL, "[JavaDoc]");
+        StringBuilder javadocURL = new StringBuilder(200);
+
+        int depth = packageName.split("\\.").length;
+
+        // One extra to account for the "ref" directory.
+
+        for (int i = 0; i <= depth; i++)
+        {
+            javadocURL.append("../");
+        }
+
+        javadocURL.append(apidocs).append("/").append(toPath(className)).append(".html");
+
+        addLink(addChild(section, "p"), javadocURL.toString(), "[JavaDoc]");
 
         if (!parents.isEmpty())
         {
@@ -369,7 +405,6 @@
 
         Document document = new Document(root);
 
-        File outputFile = new File(refDir, className + ".xml");
 
         getLog().info(String.format("Writing %s", outputFile));
 
@@ -387,7 +422,10 @@
     private void addExternalDocumentation(Element body, List<File> docSearchPath, String className)
             throws ParsingException, IOException
     {
-        String pathExtension = className.replace(".", SystemUtils.FILE_SEPARATOR) + ".xdoc";
+        String classNamePath = toPath(className);
+
+
+        String pathExtension = classNamePath + ".xdoc";
 
         for (File path : docSearchPath)
         {
@@ -414,10 +452,55 @@
                 body.appendChild(incoming);
             }
 
+            Nodes nodes = doc.query("//img/@src");
+
+            int lastslashx = classNamePath.lastIndexOf('/');
+            String packagePath = classNamePath.substring(0, lastslashx);
+
+            File generatedRefRoot = new File(generatedResourcesDirectory, REFERENCE_DIR);
+            File generatedPackageRoot = new File(generatedRefRoot, packagePath);
+
+            for (int i = 0; i < nodes.size(); i++)
+            {
+                Node src = nodes.get(i);
+
+                String srcPath = src.getValue();
+
+                File imgFile = new File(path, packagePath + "/" + srcPath);
+                File imgTargetFile = new File(generatedPackageRoot, srcPath);
+
+                copy(imgFile, imgTargetFile);
+            }
+
+
             return;
         }
     }
 
+    private void copy(File sourceFile, File targetFile) throws IOException
+    {
+        getLog().info(String.format("Copying image file %s to %s", sourceFile, targetFile));
+
+        targetFile.getParentFile().mkdirs();
+
+        byte[] buffer = new byte[20000];
+
+        InputStream in = new BufferedInputStream(new FileInputStream(sourceFile));
+        OutputStream out = new BufferedOutputStream(new FileOutputStream(targetFile));
+
+        while (true)
+        {
+            int length = in.read(buffer);
+
+            if (length < 0) break;
+
+            out.write(buffer, 0, length);
+        }
+
+        in.close();
+        out.close();
+    }
+
 
     private Map<String, ClassDescription> runJavadoc() throws MavenReportException
     {
@@ -438,15 +521,15 @@
 
         String[] arguments = {"-private", "-o", parametersPath,
 
-                              "-subpackages", rootPackage,
+                "-subpackages", rootPackage,
 
-                              "-doclet", ParametersDoclet.class.getName(),
+                "-doclet", ParametersDoclet.class.getName(),
 
-                              "-docletpath", docletPath(),
+                "-docletpath", docletPath(),
 
-                              "-sourcepath", sourcePath(),
+                "-sourcepath", sourcePath(),
 
-                              "-classpath", classPath()};
+                "-classpath", classPath()};
 
         command.addArguments(arguments);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PrimaryKeyEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PrimaryKeyEncoder.java?rev=618379&r1=618378&r2=618379&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PrimaryKeyEncoder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PrimaryKeyEncoder.java Mon Feb  4 11:01:18 2008
@@ -28,6 +28,7 @@
  * the type of the primary key, used to identify the value (which must be serializable)
  * @param <V>
  * the type of value identified by the key
+ * @see ValueEncoder
  */
 public interface PrimaryKeyEncoder<K extends Serializable, V>
 {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValueEncoder.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValueEncoder.java?rev=618379&r1=618378&r2=618379&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValueEncoder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValueEncoder.java Mon Feb  4 11:01:18 2008
@@ -14,16 +14,17 @@
 
 package org.apache.tapestry;
 
-import org.apache.tapestry.corelib.components.Select;
-
 /**
- * Used by {@link Select} (and similar components) to encode server side values into client-side strings, and back.
+ * Used to convert server side values to client-side strings.  This is used when generating
+ * a {@link org.apache.tapestry.EventContext} as part of a URL, or when components (such as {@link org.apache.tapestry.corelib.components.Select})
+ * generated other client-side strings.
  * <p/>
- * Most often a custom implementation is needed for entity type objects, where the {@link #toClient(Object)} method
+ * Often a custom implementation is needed for entity type objects, where the {@link #toClient(Object)} method
  * extracts a primary key, and the {@link #toValue(String)} re-acquires the corresponding entity object.
  *
  * @see SelectModel
  * @see org.apache.tapestry.services.ValueEncoderSource
+ * @see PrimaryKeyEncoder
  */
 public interface ValueEncoder<V>
 {

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java?rev=618379&r1=618378&r2=618379&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditForm.java Mon Feb  4 11:01:18 2008
@@ -51,7 +51,7 @@
     private String _submitLabel;
 
     /**
-     * The object to be edited by the BeanEditor. This will be read when the component renders and updated when the form
+     * The object to be edited. This will be read when the component renders and updated when the form
      * for the component is submitted. Typically, the container will listen for a "prepare" event, in order to ensure
      * that a non-null value is ready to be read or updated. Often, the BeanEditForm can create the object as needed
      * (assuming a public, no arguments constructor).  The object property defaults to a property with the same name as

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.xdoc
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.xdoc?rev=618379&r1=618378&r2=618379&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.xdoc (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditForm.xdoc Mon Feb  4 11:01:18 2008
@@ -1,14 +1,26 @@
 <document>
     <body>
-        <section name="Examples">
+
+        <p>
+            The BeanEditForm component is a convienent wrapper around three components:
+            <a href="Form.html">Form</a>,
+            <a href="Errors.html">Errors</a>
+            and<a href="BeanEditor.html">BeanEditor</a>.
+        </p>
+
+        <section name="Simple Example">
 
             <p>
-                The bean to edit will be a property of the containing page.
+                Using the bean editor, we can easily create a simple form for collecting information
+                from the user. In this example, we'll collect a little bit of data about a User:
             </p>
 
             <p>
-                You may pass override parameters for specific properties, in which case you have control
-                over how that property will be editted.
+                <img src="beaneditform_ref_simple.png"/>
+            </p>
+
+            <p>
+                The bean to edit will be a property of the containing page.
             </p>
 
             <subsection name="User.java">
@@ -48,29 +60,18 @@
 
             <subsection name="CreateUser.tml">
 
-                <p>
-                    We are overriding the editor for the age property with a Slider
-                    component (rather than the default, which would be a numeric text field).
-                    Alas this Slider component does not exist.
-                </p>
-
                 <source><![CDATA[
 <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
     <body>
         <h1>Create New User</h1>
 
-        <t:beaneditform t:id="user" submitlabel="message:create-user">
-            <t:parameter name="age">
-               <t:label for="age"/>
-               <t:slider min="18" max="99" t:id="age" value="user.age"/>
-            </t:parameter>
-        </t:beaneditform>
+        <t:beaneditform t:id="user" submitlabel="message:create-user"/>
     </body>
 </html>
 ]]></source>
 
                 <p>
-                    Nominally, we should have to bind the object parameterof the BeanEditForm component. However, as
+                    Nominally, we should have to bind the object parameter of the BeanEditForm component. However, as
                     a convienience, Tapestry has defaulted the object parameter
                     based on the component id. This works because the CreateUser class
                     includes a property named "user", which matches the BeanEditForm component's id.
@@ -88,16 +89,6 @@
                     <code><![CDATA[<t:beaneditform t:id="address" object="registration.address"/>]]></code>
                 </p>
 
-                <p>
-                    The
-                    <code><![CDATA[<t:parameter>]]></code>
-                    element
-                    is an
-                    <em>override</em>
-                    for the property. The name is
-                    matched against a property of the bean. We need to provide a Label and an appropriate
-                    editor component (here, the hypothetical Slider component).
-                </p>
 
             </subsection>
 
@@ -165,7 +156,7 @@
                 <p>
                     Notice that we don't instantiate the User object ourselves; instead we let the BeanEditForm
                     component
-                    do that for us. It's capable of doing so because the User class has the default public no arguments
+                    do that for us. It's capable of doing so because the User class has a default public no arguments
                     constructor.
                 </p>
 
@@ -181,6 +172,103 @@
                     Returning a class from an event handler method (<code>UserAdmin.class</code>) will
                     activate the indicated page as the response page. As always, a redirect to to the response page is
                     sent to the client.
+                </p>
+
+            </subsection>
+
+        </section>
+
+        <section name="Validations and Overrides">
+
+            <p>
+                By placing some annotations on the properties of the User class, we can enable client-side
+                validations. In addition, we can override the default editor components for a property
+                to add some additional instructions.
+            </p>
+
+            <subsection name="User.java (partial)">
+
+                <source><![CDATA[
+    @Validate("required")
+    public String getFirstName() { return _firstName; }
+
+    public void setFirstName(String firstName) { _firstName = firstName; }
+
+    @Validate("required")
+    public String getLastName() { return _lastName; }
+
+    public void setLastName(String lastName) { _lastName = lastName; }
+
+    @Validate("min=18,max=99")
+    public int getAge() { return _age; }
+
+    public void setAge(int age) { _age = age; }]]>    </source>
+
+                <p>
+                    The new @Validate annotations added to the first name and last name properties indicates that a
+                    non-blank
+                    value must be provided. For the age property we are setting minimum and maximum values as well.
+                </p>
+
+                <p>
+                    Validation for each field occurs when the form is submitted, and when the user tabs out of a field.
+                    If you submit
+                    immediately, Tapestry will display popup bubbles for each field identifying the error:
+                </p>
+
+                <p>
+                    <img src="beaneditform_ref_validation1.png"/>
+                </p>
+
+                <p>
+                    In addition, fields with errors are marked with a red X, the font for the first turns red, and the
+                    label
+                    for the field turns red. We're providing a lot of feedback to the user.
+                    After a moment, all the bubbles except for the current field fade. Bubbles fade in and out as you
+                    tab from field to field.
+                </p>
+
+                <p>
+                    <img src="beaneditform_ref_validation2.png"/>
+                </p>
+
+
+            </subsection>
+
+
+            <subsection name="CreateUser.tml (partial)">
+
+                <p>
+                    We can customize how individual properties are editted. Here we'll
+                    add a small reminder next to the age property:
+                </p>
+
+                <p>
+                    <img src="beaneditform_ref_customized.png"/>
+                </p>
+
+                <source><![CDATA[
+        <t:beaneditform t:id="user" submitlabel="message:create-user">
+            <t:parameter name="age">
+                <t:label for="age"/>
+                <t:textfield t:id="age" value="user.age"/>
+                <em>
+                    Users must be between 18 and 99.
+                </em>
+            </t:parameter>
+        </t:beaneditform>]]></source>
+
+                <p>
+                    The
+                    <code><![CDATA[<t:parameter>]]></code>
+                    element
+                    is an
+                    <em>override</em>
+                    for the property. The name is
+                    matched against a property of the bean. We need to provide a
+                    <a href="Label.html">Label</a>
+                    component, and an appropriate
+                    editor component.
                 </p>
 
             </subsection>

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.xdoc
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.xdoc?rev=618379&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.xdoc (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/BeanEditor.xdoc Mon Feb  4 11:01:18 2008
@@ -0,0 +1,7 @@
+<document>
+    <body>
+        See the
+        <a href="BeanEditForm.html">BeanEditForm</a>
+        documentation for examples of how to use and customize this component.
+    </body>
+</document>
\ No newline at end of file

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_customized.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_customized.png?rev=618379&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_customized.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_simple.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_simple.png?rev=618379&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_simple.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_validation1.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_validation1.png?rev=618379&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_validation1.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_validation2.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_validation2.png?rev=618379&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/components/beaneditform_ref_validation2.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css?rev=618379&r1=618378&r2=618379&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css Mon Feb  4 11:01:18 2008
@@ -132,10 +132,6 @@
     width: auto;
 }
 
-FORM.t-beaneditor LABEL:after {
-    content: ":";
-}
-
 DIV.t-beaneditor-row {
     padding: 4px 0px 2px 0px;
 }
@@ -145,7 +141,7 @@
 }
 
 DIV.t-beaneditor LABEL, DIV.t-beandisplay DIV.t-beandisplay-label {
-    width: 10%;
+    width: 250px;
     display: block;
     float: left;
     text-align: right;

Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/conf.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/conf.apt?rev=618379&r1=618378&r2=618379&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/conf.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/conf.apt Mon Feb  4 11:01:18 2008
@@ -85,7 +85,6 @@
 
 
   [tapestry.compress-whitespace]
-
     A flag (true or false).  When true (the default) whitespace in component templates is compressed by default
     (this can be fine-tuned using the standard xml:space attribute on an element in the template).
     When this flag is false, then whitespace is retained by default (but can still be overridden).