| /* |
| * Copyright 2004-2005 The Apache Software Foundation. |
| * |
| * Licensed 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.xmlDefinition; |
| |
| import org.apache.tiles.ComponentDefinition; |
| import org.apache.tiles.NoSuchDefinitionException; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import java.util.Iterator; |
| |
| /** |
| *A definition read from an XML definitions file. |
| */ |
| public class XmlDefinition extends ComponentDefinition |
| { |
| /** |
| * Extends attribute value. |
| */ |
| private String inherit; |
| |
| /** Commons Logging instance. */ |
| protected static Log log = LogFactory.getLog(XmlDefinition.class); |
| |
| /** |
| * Used for resolving inheritance. |
| */ |
| private boolean isVisited=false; |
| |
| |
| /** |
| * Constructor. |
| */ |
| public XmlDefinition() |
| { |
| super(); |
| //if(debug) |
| //System.out.println( "create definition" ); |
| } |
| |
| /** |
| * Add an attribute to this component. |
| * |
| * @param attribute Attribute to add. |
| */ |
| public void addAttribute( XmlAttribute attribute) |
| { |
| putAttribute( attribute.getName(), attribute.getValue() ); |
| } |
| |
| /** |
| * Set extends. |
| * |
| * @param name Name of the extended definition. |
| */ |
| public void setExtends(String name) |
| { |
| inherit = name; |
| } |
| |
| /** |
| * Get extends. |
| * |
| * @return Name of the extended definition. |
| */ |
| public String getExtends() |
| { |
| return inherit; |
| } |
| |
| /** |
| * Get extends flag. |
| * |
| */ |
| public boolean isExtending( ) |
| { |
| return inherit!=null; |
| } |
| |
| /** |
| * Set isVisited. |
| * |
| */ |
| public void setIsVisited( boolean isVisited ) |
| { |
| this.isVisited = isVisited; |
| } |
| |
| /** |
| * Resolve inheritance. |
| * First, resolve parent's inheritance, then set path to the parent's path. |
| * Also copy attributes setted in parent, and not set in child |
| * If instance doesn't extend anything, do nothing. |
| * @throws NoSuchDefinitionException If an inheritance can not be solved. |
| */ |
| public void resolveInheritance( XmlDefinitionsSet definitionsSet ) |
| throws NoSuchDefinitionException |
| { |
| // Already done, or not needed ? |
| if( isVisited || !isExtending() ) |
| return; |
| |
| if(log.isDebugEnabled()) |
| log.debug( "Resolve definition for child name='" + getName() |
| + "' extends='" + getExtends() + "'."); |
| |
| // Set as visited to avoid endless recurisvity. |
| setIsVisited( true ); |
| |
| // Resolve parent before itself. |
| XmlDefinition parent = definitionsSet.getDefinition( getExtends() ); |
| if( parent == null ) |
| { // error |
| String msg = "Error while resolving definition inheritance: child '" |
| + getName() + "' can't find its ancestor '" |
| + getExtends() + "'. Please check your description file."; |
| log.error( msg ); |
| // to do : find better exception |
| throw new NoSuchDefinitionException( msg ); |
| } |
| |
| parent.resolveInheritance( definitionsSet ); |
| |
| // Iterate on each parent's attribute and add it if not defined in child. |
| Iterator parentAttributes = parent.getAttributes().keySet().iterator(); |
| while( parentAttributes.hasNext() ) |
| { |
| String name = (String)parentAttributes.next(); |
| if( !getAttributes().containsKey(name) ) |
| putAttribute( name, parent.getAttribute(name) ); |
| } |
| // Set path and role if not setted |
| if( path == null ) |
| setPath( parent.getPath() ); |
| if( role == null ) |
| setRole( parent.getRole() ); |
| if( controller==null ) |
| { |
| setController( parent.getController()); |
| setControllerType( parent.getControllerType()); |
| } |
| } |
| |
| /** |
| * Overload this definition with passed child. |
| * All attributes from child are copied to this definition. Previous attributes with |
| * same name are disguarded. |
| * Special attribute 'path','role' and 'extends' are overloaded if defined in child. |
| * @param child Child used to overload this definition. |
| */ |
| public void overload( XmlDefinition child ) |
| { |
| if( child.getPath() != null ) |
| { |
| path = child.getPath(); |
| } |
| if( child.getExtends() != null ) |
| { |
| inherit = child.getExtends(); |
| } |
| if( child.getRole() != null ) |
| { |
| role = child.getRole(); |
| } |
| if( child.getController()!=null ) |
| { |
| controller = child.getController(); |
| controllerType = child.getControllerType(); |
| } |
| // put all child attributes in parent. |
| attributes.putAll( child.getAttributes()); |
| } |
| } |