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 <tiles:definition> 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[