001// Copyright 2004, 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.hivemind.schema.rules;
016
017import org.apache.commons.logging.Log;
018import org.apache.commons.logging.LogFactory;
019import org.apache.hivemind.Element;
020import org.apache.hivemind.ErrorHandler;
021import org.apache.hivemind.Location;
022import org.apache.hivemind.schema.SchemaProcessor;
023import org.apache.hivemind.schema.Translator;
024import org.apache.hivemind.util.PropertyUtils;
025
026/**
027 * Reads an attribute of an element and uses it to set a property of the top object on the stack.
028 * Created from the <code>&lt;read-attribute&gt;</code> element.
029 * 
030 * @author Howard Lewis Ship
031 */
032public class ReadAttributeRule extends BaseRule
033{
034
035    private static final Log LOG = LogFactory.getLog(ReadAttributeRule.class);
036
037    private String _attributeName;
038
039    private String _propertyName;
040
041    private boolean _skipIfNull = true;
042
043    private String _translator;
044
045    public ReadAttributeRule()
046    {
047    }
048
049    public ReadAttributeRule(String attributeName, String propertyName, String translator,
050            Location location)
051    {
052        setLocation(location);
053
054        _attributeName = attributeName;
055        _propertyName = propertyName;
056        _translator = translator;
057    }
058
059    public void begin(SchemaProcessor processor, Element element)
060    {
061        String rawValue = element.getAttributeValue(_attributeName);
062
063        if (rawValue == null && _skipIfNull)
064            return;
065
066        String value = RuleUtils.processText(processor, element, rawValue);
067
068        Object target = processor.peek();
069
070        try
071        {
072            Translator t = _translator == null ? processor.getAttributeTranslator(_attributeName)
073                    : processor.getTranslator(_translator);
074
075            Class propertyType = PropertyUtils.getPropertyType(target, _propertyName);
076
077            Object finalValue = t.translate(
078                    processor.getContributingModule(),
079                    propertyType,
080                    value,
081                    element.getLocation());
082
083            PropertyUtils.write(target, _propertyName, finalValue);
084
085        }
086        catch (Exception ex)
087        {
088            ErrorHandler eh = processor.getContributingModule().getErrorHandler();
089
090            eh.error(LOG, RulesMessages
091                    .readAttributeFailure(_attributeName, element, processor, ex), element
092                    .getLocation(), ex);
093        }
094
095    }
096
097    public String getAttributeName()
098    {
099        return _attributeName;
100    }
101
102    public String getPropertyName()
103    {
104        return _propertyName;
105    }
106
107    public boolean getSkipIfNull()
108    {
109        return _skipIfNull;
110    }
111
112    /**
113     * @since 1.1
114     */
115    public String getTranslator()
116    {
117        return _translator;
118    }
119
120    public void setAttributeName(String string)
121    {
122        _attributeName = string;
123    }
124
125    public void setPropertyName(String string)
126    {
127        _propertyName = string;
128    }
129
130    public void setSkipIfNull(boolean b)
131    {
132        _skipIfNull = b;
133    }
134
135    public void setTranslator(String string)
136    {
137        _translator = string;
138    }
139
140}