001/*
002 * Copyright (c) 2004-2012, Willem Cazander
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
006 * that the following conditions are met:
007 * 
008 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the
009 *   following disclaimer.
010 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
011 *   the following disclaimer in the documentation and/or other materials provided with the distribution.
012 * 
013 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
014 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
015 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
016 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
018 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
019 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
020 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
021 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
022 */
023
024package org.x4o.xml.impl;
025
026import java.util.Locale;
027import java.util.logging.Logger;
028
029import javax.el.ValueExpression;
030
031import org.x4o.xml.conv.ObjectConverterException;
032import org.x4o.xml.element.Element;
033import org.x4o.xml.element.ElementAttributeValueParser;
034import org.x4o.xml.element.ElementAttributeValueParserException;
035import org.x4o.xml.element.ElementClassAttribute;
036import org.x4o.xml.element.ElementInterface;
037
038
039/**
040 * An DefaultElementAttributeValueParser.
041 * 
042 * @author Willem Cazander
043 * @version 1.0 Feb 16, 2007
044 */
045public class DefaultElementAttributeValueParser implements ElementAttributeValueParser {
046
047
048        private Logger logger = null;
049        
050        public DefaultElementAttributeValueParser() {
051                logger = Logger.getLogger(DefaultElementAttributeValueParser.class.getName());
052        }
053        
054        
055        /**
056         * @see org.x4o.xml.element.ElementAttributeValueParser#getParameterValue(java.lang.String, java.lang.String, org.x4o.xml.element.Element)
057         */
058        public Object getParameterValue(String name, String valueString, Element element) throws ElementAttributeValueParserException,ObjectConverterException {
059                Object value = valueString;
060
061                if (isELParameter(name, valueString, element)) {
062                        value = getELParameterValue(valueString, element);
063                }
064                return getConvertedParameterValue(name, value, element);
065        }
066
067
068
069
070        /**
071         * @throws ObjectConverterException 
072         * @see org.x4o.xml.element.ElementAttributeValueParser#getConvertedParameterValue(java.lang.String, java.lang.Object, org.x4o.xml.element.Element)
073         */
074        public Object getConvertedParameterValue(String name,Object value, Element element) throws ElementAttributeValueParserException, ObjectConverterException {
075                //bit slow here
076                if (value==null) {
077                        return null; // TODO: make setting for null
078                }
079                        
080                // do converts for ElementClass
081                ElementClassAttribute attr = element.getElementClass().getElementClassAttributeByName(name);
082                if (attr!=null && attr.getObjectConverter()!=null && value.getClass().isAssignableFrom(attr.getObjectConverter().getObjectClassTo())==false) {
083                        logger.finer("attr conv: "+attr.getObjectConverter()+" for name: "+name);
084                        Object result = attr.getObjectConverter().convertTo(value.toString(), Locale.getDefault());
085                        return result;
086                }
087                // check interfaces
088                if (element.getElementObject()==null) {
089                        return value;
090                }
091                for (ElementInterface ei:element.getElementLanguage().findElementInterfaces(element.getElementObject())) {
092                        logger.finer("Found interface match executing converter.");
093                        for (ElementClassAttribute attrClass:ei.getElementClassAttributes()) {
094                                if (name.equals(attrClass.getName())==false) {
095                                        continue;
096                                }
097                                if (attrClass.getObjectConverter()==null) {
098                                        continue;
099                                }
100                                if (value.getClass().isAssignableFrom(attrClass.getObjectConverter().getObjectClassTo())) {
101                                        continue; // make flag ?
102                                }
103                                logger.finest("attr conv interface: "+attrClass.getObjectConverter()+" for name: "+name);
104                                Object result = attrClass.getObjectConverter().convertTo(value.toString(), Locale.getDefault());
105                                return result; // ??
106                        }
107                }
108                return value;
109        }
110        
111        /**
112         * @see org.x4o.xml.element.ElementAttributeValueParser#getELParameterValue(java.lang.String, org.x4o.xml.element.Element)
113         */
114        public Object getELParameterValue(String value, Element element) throws ElementAttributeValueParserException {
115                ValueExpression e = element.getElementLanguage().getExpressionFactory().createValueExpression(element.getElementLanguage().getELContext(), (String)value,Object.class);
116                return e.getValue(element.getElementLanguage().getELContext());
117        }
118
119        /**
120         * @see org.x4o.xml.element.ElementAttributeValueParser#isELParameter(java.lang.String, java.lang.String, org.x4o.xml.element.Element)
121         */
122        public boolean isELParameter(String name, String value, Element element) {
123                if (value==null) {
124                        return false;
125                }
126                if (value.startsWith("${")==false) {
127                        return false;
128                }
129                if (element==null) {
130                        return true;    // null element disables checks
131                }
132                ElementClassAttribute attr = element.getElementClass().getElementClassAttributeByName(name);
133                if (attr!=null && attr.getRunResolveEL()!=null && attr.getRunResolveEL()==false) {
134                        logger.finest("Skipping EL parsing for: "+name);
135                        return false;
136                }
137                
138                for (ElementInterface ei:element.getElementLanguage().findElementInterfaces(element.getElementObject())) {
139                        logger.finest("Found interface match checking disables el parameters.");
140                        
141                        attr = ei.getElementClassAttributeByName(name);
142                        if (attr!=null && attr.getRunResolveEL()!=null && attr.getRunResolveEL()==false) {
143                                logger.finest("Skipping EL parsing for: "+name+" in interface element.");
144                                return false;
145                        }
146                }
147                return true;
148        }
149}