Author: apetrelli
Date: Wed Feb 27 11:28:56 2008
New Revision: 631684

URL: http://svn.apache.org/viewvc?rev=631684&view=rev
Log:
TILES-85
Added nested definitions to "put-attribute" and "tiles:putAttribute" tags.

Added:
    
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTagParent.java
   (with props)
Modified:
    
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java
    
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingKeyedDefinitionsFactoryTilesContainer.java
    
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingTilesContainer.java
    
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/DefinitionManager.java
    
tiles/framework/trunk/tiles-core/src/main/resources/org/apache/tiles/resources/tiles-config_2_1.dtd
    
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/PutAttributeTag.java
    
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTag.java
    
tiles/framework/trunk/tiles-jsp/src/main/resources/META-INF/tld/tiles-jsp.tld

Modified: 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java?rev=631684&r1=631683&r2=631684&view=diff
==============================================================================
--- 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java
 (original)
+++ 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java
 Wed Feb 27 11:28:56 2008
@@ -25,6 +25,7 @@
 import org.apache.commons.digester.Rule;
 import org.apache.tiles.Attribute;
 import org.apache.tiles.Definition;
+import org.apache.tiles.TilesRuntimeException;
 import org.apache.tiles.context.ListAttribute;
 import org.apache.tiles.definition.DefinitionsFactoryException;
 import org.apache.tiles.definition.DefinitionsReader;
@@ -83,7 +84,12 @@
     /**
      * Intercepts a <put-attribute> tag.
      */
-    private static final String PUT_TAG = DEFINITION_TAG + "/put-attribute";
+    private static final String PUT_TAG = "*/definition/put-attribute";
+
+    /**
+     * Intercepts a <definition> inside a  <put-attribute> tag.
+     */
+    private static final String PUT_DEFINITION_TAG = 
"*/put-attribute/definition";
 
     /**
      * Intercepts a <put-list-attribute> tag.
@@ -180,6 +186,28 @@
     }
 
     /**
+     * Digester rule to manage assignment of a nested definition in an 
attribute
+     * value.
+     *
+     * @since 2.1.0
+     */
+    public class AddNestedDefinitionRule extends Rule {
+
+        /** [EMAIL PROTECTED] */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes)
+                throws Exception {
+            Definition definition = (Definition) digester.peek(0);
+            if (definition.getName() == null) {
+                definition.setName(getNextUniqueDefinitionName(definitions));
+            }
+            Attribute attribute = (Attribute) digester.peek(1);
+            attribute.setValue(definition.getName());
+            attribute.setRenderer("definition");
+        }
+    }
+
+    /**
      * <code>Digester</code> object used to read Definition data
      * from the source.
      */
@@ -206,6 +234,12 @@
     private boolean inited = false;
 
     /**
+     * Index to be used to create unique definition names for anonymous
+     * (nested) definitions.
+     */
+    private int anonymousDefinitionIndex = 1;
+
+    /**
      * Creates a new instance of DigesterDefinitionsReader.
      */
     public DigesterDefinitionsReader() {
@@ -331,6 +365,13 @@
         digester.addObjectCreate(DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
         digester.addSetProperties(DEFINITION_TAG);
         digester.addSetNext(DEFINITION_TAG, "addDefinition", 
DEFINITION_HANDLER_CLASS);
+
+        // nested definition rules
+        digester.addObjectCreate(PUT_DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addSetProperties(PUT_DEFINITION_TAG);
+        digester.addSetRoot(PUT_DEFINITION_TAG, "addDefinition");
+        digester.addRule(PUT_DEFINITION_TAG, new AddNestedDefinitionRule());
+
         // put / putAttribute rules
         // Rules for a same pattern are called in order, but rule.end() are 
called
         // in reverse order.
@@ -386,7 +427,13 @@
      * @param definition The Definition object to be added.
      */
     public void addDefinition(Definition definition) {
-        definitions.put(definition.getName(), definition);
+        String name = definition.getName();
+        if (name == null) {
+            throw new TilesRuntimeException(
+                    "A root definition has been defined with no name");
+        }
+
+        definitions.put(name, definition);
     }
 
     /**
@@ -426,5 +473,23 @@
                 "/org/apache/tiles/resources/tiles-config_2_1.dtd"};
         }
         return registrations;
+    }
+
+    /**
+     * Create a unique definition name usable to store anonymous definitions.
+     *
+     * @param definitions The already created definitions.
+     * @return The unique definition name to be used to store the definition.
+     */
+    protected String getNextUniqueDefinitionName(
+            Map<String, Definition> definitions) {
+        String candidate;
+
+        do {
+            candidate = "$anonymousDefinition" + anonymousDefinitionIndex;
+            anonymousDefinitionIndex++;
+        } while (definitions.containsKey(candidate));
+
+        return candidate;
     }
 }

Modified: 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingKeyedDefinitionsFactoryTilesContainer.java
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingKeyedDefinitionsFactoryTilesContainer.java?rev=631684&r1=631683&r2=631684&view=diff
==============================================================================
--- 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingKeyedDefinitionsFactoryTilesContainer.java
 (original)
+++ 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingKeyedDefinitionsFactoryTilesContainer.java
 Wed Feb 27 11:28:56 2008
@@ -125,8 +125,7 @@
             TilesRequestContext request) throws DefinitionsFactoryException {
         DefinitionManager mgr = getProperDefinitionManager(
                 getDefinitionsFactoryKey(request));
-        Definition def = new Definition(definition);
-        mgr.addDefinition(def, request);
+        mgr.addDefinition(definition, request);
     }
 
     /**

Modified: 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingTilesContainer.java
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingTilesContainer.java?rev=631684&r1=631683&r2=631684&view=diff
==============================================================================
--- 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingTilesContainer.java
 (original)
+++ 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingTilesContainer.java
 Wed Feb 27 11:28:56 2008
@@ -86,7 +86,6 @@
      */
     protected void register(Definition definition,
             TilesRequestContext request) throws DefinitionsFactoryException {
-        Definition def = new Definition(definition);
-        mgr.addDefinition(def, request);
+        mgr.addDefinition(definition, request);
     }
 }

Modified: 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/DefinitionManager.java
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/DefinitionManager.java?rev=631684&r1=631683&r2=631684&view=diff
==============================================================================
--- 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/DefinitionManager.java
 (original)
+++ 
tiles/framework/trunk/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/DefinitionManager.java
 Wed Feb 27 11:28:56 2008
@@ -64,6 +64,12 @@
     private String definitionsAttributeName;
 
     /**
+     * Index to be used to create unique definition names for anonymous
+     * (nested) definitions.
+     */
+    private int anonymousDefinitionIndex = 1;
+
+    /**
      * Constructor.
      */
     public DefinitionManager() {
@@ -131,13 +137,17 @@
     public void addDefinition(Definition definition,
             TilesRequestContext request)
         throws DefinitionsFactoryException {
+        Map<String, Definition> definitions = getOrCreateDefinitions(request);
+        if (definition.getName() == null) {
+            definition.setName(getNextUniqueDefinitionName(definitions));
+        }
         validate(definition);
 
         if (definition.isExtending()) {
             this.resolveInheritance(definition, request);
         }
 
-        getOrCreateDefinitions(request).put(definition.getName(), definition);
+        definitions.put(definition.getName(), definition);
     }
 
     /**
@@ -213,7 +223,7 @@
 
         // Resolve parent before itself.
         resolveInheritance(parent, request);
-        overload(parent, definition);
+        definition.inherit(parent);
     }
 
     /**
@@ -264,5 +274,23 @@
         }
 
         return definitions;
+    }
+
+    /**
+     * Create a unique definition name usable to store anonymous definitions.
+     *
+     * @param definitions The already created definitions.
+     * @return The unique definition name to be used to store the definition.
+     */
+    protected String getNextUniqueDefinitionName(
+            Map<String, Definition> definitions) {
+        String candidate;
+
+        do {
+            candidate = "$anonymousMutableDefinition" + 
anonymousDefinitionIndex;
+            anonymousDefinitionIndex++;
+        } while (definitions.containsKey(candidate));
+
+        return candidate;
     }
 }

Modified: 
tiles/framework/trunk/tiles-core/src/main/resources/org/apache/tiles/resources/tiles-config_2_1.dtd
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-core/src/main/resources/org/apache/tiles/resources/tiles-config_2_1.dtd?rev=631684&r1=631683&r2=631684&view=diff
==============================================================================
--- 
tiles/framework/trunk/tiles-core/src/main/resources/org/apache/tiles/resources/tiles-config_2_1.dtd
 (original)
+++ 
tiles/framework/trunk/tiles-core/src/main/resources/org/apache/tiles/resources/tiles-config_2_1.dtd
 Wed Feb 27 11:28:56 2008
@@ -108,9 +108,11 @@
 -->
 <!ATTLIST definition       extends          %DefinitionName; #IMPLIED>
 <!--
[EMAIL PROTECTED] name           The unique identifier for this definition.
[EMAIL PROTECTED] name           The unique identifier for this definition. 
Required when
+                     it is a root definition, while it is implied in nested
+                     definitions. 
 -->
-<!ATTLIST definition       name             %DefinitionName; #REQUIRED>
+<!ATTLIST definition       name             %DefinitionName; #IMPLIED>
 <!--
 @attr role           Security role name that is allowed access to this 
definition
                      object. The definition is inserted only if the role name 
is
@@ -129,7 +131,7 @@
      specify the tiles attribute name and its value. The tiles value can be
      specified as an xml attribute, or in the body of the <put-attribute> tag.
 -->
-<!ELEMENT put-attribute (#PCDATA)>
+<!ELEMENT put-attribute ( (definition*) )>
 <!ATTLIST put-attribute     id               ID              #IMPLIED>
 <!--
 @attr name           The unique identifier for this put-attribute.

Modified: 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/PutAttributeTag.java
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/PutAttributeTag.java?rev=631684&r1=631683&r2=631684&view=diff
==============================================================================
--- 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/PutAttributeTag.java
 (original)
+++ 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/PutAttributeTag.java
 Wed Feb 27 11:28:56 2008
@@ -23,6 +23,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.tiles.jsp.taglib.definition.DefinitionTagParent;
 
 import javax.servlet.jsp.JspException;
 import javax.servlet.jsp.tagext.TagSupport;
@@ -67,7 +68,8 @@
  *
  * @version $Rev$ $Date$
  */
-public class PutAttributeTag extends RoleSecurityTagSupport {
+public class PutAttributeTag extends RoleSecurityTagSupport implements
+        DefinitionTagParent {
 
     /**
      * The logging object.
@@ -214,11 +216,20 @@
      * @throws JspException if a JSP exception has occurred
      */
     public int doAfterBody() throws JspException {
-        if (bodyContent != null) {
+        if (value == null && bodyContent != null) {
             value = bodyContent.getString();
             type = "string";
         }
         return (SKIP_BODY);
+    }
+
+    /** [EMAIL PROTECTED] */
+    public void processNestedDefinitionName(String definitionName)
+            throws JspException {
+        value = definitionName;
+        if (type == null) {
+            type = "definition";
+        }
     }
 
     /** [EMAIL PROTECTED] */

Modified: 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTag.java
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTag.java?rev=631684&r1=631683&r2=631684&view=diff
==============================================================================
--- 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTag.java
 (original)
+++ 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTag.java
 Wed Feb 27 11:28:56 2008
@@ -209,6 +209,7 @@
     public int doEndTag() throws JspException {
         try {
             container.register(definition, pageContext);
+            callParent();
         } catch (TilesException e) {
             throw new JspException("Unable to add definition. " , e);
         }
@@ -227,5 +228,43 @@
             nestedTag.getRole(), nestedTag.getType());
         definition.putAttribute(nestedTag.getName(), attr, nestedTag
                 .isCascade());
+    }
+
+    /**
+     * Find parent tag which must implement [EMAIL PROTECTED] 
DefinitionTagParent}.
+     * @throws JspException If we can't find an appropriate enclosing tag.
+     */
+    protected void callParent() throws JspException {
+        // Get enclosing parent
+        DefinitionTagParent enclosingParent =
+                findEnclosingDefinitionTagParent();
+        if (enclosingParent != null) {
+            enclosingParent.processNestedDefinitionName(definition.getName());
+        }
+    }
+
+    /**
+     * Find parent tag which must implement AttributeContainer.
+     * @throws JspException If we can't find an appropriate enclosing tag.
+     * @return The parent tag.
+     */
+    protected DefinitionTagParent findEnclosingDefinitionTagParent() throws 
JspException {
+        try {
+            DefinitionTagParent parent =
+                    (DefinitionTagParent) findAncestorWithClass(this,
+                            DefinitionTagParent.class);
+
+            if (parent == null && name == null) {
+                throw new JspException(
+                        "Error - tag definition : enclosing tag doesn't accept 
'definition'"
+                                + " tag and a name was not specified.");
+            }
+
+            return parent;
+
+        } catch (ClassCastException ex) { // Is it possibile?
+            throw new JspException(
+                    "Error - tag definition : enclosing tag doesn't accept 
'definition' tag.", ex);
+        }
     }
 }

Added: 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTagParent.java
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTagParent.java?rev=631684&view=auto
==============================================================================
--- 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTagParent.java
 (added)
+++ 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTagParent.java
 Wed Feb 27 11:28:56 2008
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.tiles.jsp.taglib.definition;
+
+import javax.servlet.jsp.JspException;
+
+/**
+ * Tag classes implementing this interface can contain nested
+ * [EMAIL PROTECTED] DefinitionTag}. This interface defines a method called by 
nested
+ * tags.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface DefinitionTagParent {
+
+    /**
+     * Process the nested &lt;tiles:definition&gt; tag.
+     *
+     * @param definitionName Nested definition name.
+     * @throws JspException If something goes wrong during the processing.
+     */
+    void processNestedDefinitionName(String definitionName)
+            throws JspException;
+}

Propchange: 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTagParent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
tiles/framework/trunk/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/definition/DefinitionTagParent.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: 
tiles/framework/trunk/tiles-jsp/src/main/resources/META-INF/tld/tiles-jsp.tld
URL: 
http://svn.apache.org/viewvc/tiles/framework/trunk/tiles-jsp/src/main/resources/META-INF/tld/tiles-jsp.tld?rev=631684&r1=631683&r2=631684&view=diff
==============================================================================
--- 
tiles/framework/trunk/tiles-jsp/src/main/resources/META-INF/tld/tiles-jsp.tld 
(original)
+++ 
tiles/framework/trunk/tiles-jsp/src/main/resources/META-INF/tld/tiles-jsp.tld 
Wed Feb 27 11:28:56 2008
@@ -25,7 +25,7 @@
     "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
     "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd";>
 <taglib>
-   <tlib-version>2.0</tlib-version>
+   <tlib-version>2.1</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>tiles</short-name>
    <uri>http://tiles.apache.org/tags-tiles</uri>
@@ -320,7 +320,7 @@
          </description>
       <attribute>
          <name>name</name>
-         <required>true</required>
+         <required>false</required>
          <rtexprvalue>true</rtexprvalue>
          <description>
          <![CDATA[


Reply via email to