View Javadoc

1   /*
2    * $Id: XmlDefinition.java 421151 2006-07-12 06:07:14Z wsmoak $
3    *
4    * Copyright 1999-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  
20  package org.apache.struts.tiles.xmlDefinition;
21  
22  import java.util.Iterator;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.struts.tiles.ComponentDefinition;
27  import org.apache.struts.tiles.NoSuchDefinitionException;
28  
29  /***
30    *A definition read from an XML definitions file.
31    */
32  public class XmlDefinition extends ComponentDefinition
33  {
34    /***
35     * Extends attribute value.
36     */
37    private String inherit;
38  
39      /*** Commons Logging instance. */
40     protected static Log log = LogFactory.getLog(XmlDefinition.class);
41  
42    /***
43     * Used for resolving inheritance.
44     */
45    private boolean isVisited=false;
46  
47  
48       /***
49        * Constructor.
50        */
51     public XmlDefinition()
52     {
53     super();
54     //if(debug)
55       //System.out.println( "create definition" );
56     }
57  
58    /***
59     * Add an attribute to this component.
60     *
61     * @param attribute Attribute to add.
62     */
63    public void addAttribute( XmlAttribute attribute)
64      {
65      putAttribute( attribute.getName(), attribute.getValue() );
66      }
67  
68    /***
69     * Set extends.
70     *
71     * @param name Name of the extended definition.
72     */
73    public void setExtends(String name)
74      {
75      inherit = name;
76      }
77  
78    /***
79     * Get extends.
80     *
81     * @return Name of the extended definition.
82     */
83    public String getExtends()
84      {
85      return inherit;
86      }
87  
88    /***
89     * Get extends flag.
90     *
91     */
92    public boolean isExtending( )
93      {
94      return inherit!=null;
95      }
96  
97    /***
98     * Set isVisited.
99     *
100    */
101   public void setIsVisited( boolean isVisited )
102     {
103     this.isVisited = isVisited;
104     }
105 
106     /***
107      * Resolve inheritance.
108      * First, resolve parent's inheritance, then set path to the parent's path.
109      * Also copy attributes setted in parent, and not set in child
110      * If instance doesn't extend anything, do nothing.
111      * @throws NoSuchDefinitionException If an inheritance can not be solved.
112      */
113   public void resolveInheritance( XmlDefinitionsSet definitionsSet )
114     throws NoSuchDefinitionException
115     {
116       // Already done, or not needed ?
117     if( isVisited || !isExtending() )
118       return;
119 
120     if(log.isDebugEnabled())
121       log.debug( "Resolve definition for child name='" + getName()
122               + "' extends='" + getExtends() + "'.");
123 
124       // Set as visited to avoid endless recurisvity.
125     setIsVisited( true );
126 
127       // Resolve parent before itself.
128     XmlDefinition parent = definitionsSet.getDefinition( getExtends() );
129     if( parent == null )
130       { // error
131       String msg = "Error while resolving definition inheritance: child '"
132                            + getName() +    "' can't find its ancestor '"
133                            + getExtends() + 
134                            "'. Please check your description file.";
135       log.error( msg );
136         // to do : find better exception
137       throw new NoSuchDefinitionException( msg );
138       }
139 
140     parent.resolveInheritance( definitionsSet );
141 
142       // Iterate on each parent's attribute and add it if not defined in child.
143     Iterator parentAttributes = parent.getAttributes().keySet().iterator();
144     while( parentAttributes.hasNext() )
145       {
146       String name = (String)parentAttributes.next();
147       if( !getAttributes().containsKey(name) )
148         putAttribute( name, parent.getAttribute(name) );
149       }
150       // Set path and role if not setted
151     if( path == null )
152       setPath( parent.getPath() );
153     if( role == null )
154       setRole( parent.getRole() );
155     if( controller==null )
156       {
157       setController( parent.getController());
158       setControllerType( parent.getControllerType());
159       }
160     }
161 
162   /***
163    * Overload this definition with passed child.
164    * All attributes from child are copied to this definition. Previous 
165    * attributes with same name are disguarded.
166    * Special attribute 'path','role' and 'extends' are overloaded if defined 
167    * in child.
168    * @param child Child used to overload this definition.
169    */
170   public void overload( XmlDefinition child )
171     {
172     if( child.getPath() != null )
173       {
174       path = child.getPath();
175       }
176     if( child.getExtends() != null )
177       {
178       inherit = child.getExtends();
179       }
180     if( child.getRole() != null )
181       {
182       role = child.getRole();
183       }
184     if( child.getController()!=null )
185       {
186       controller = child.getController();
187       controllerType =  child.getControllerType();
188       }
189       // put all child attributes in parent.
190     attributes.putAll( child.getAttributes());
191     }
192 }