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    
015    package org.apache.hivemind.schema.rules;
016    
017    import java.lang.reflect.Field;
018    import java.util.Map;
019    
020    import org.apache.hivemind.ApplicationRuntimeException;
021    import org.apache.hivemind.HiveMind;
022    import org.apache.hivemind.Location;
023    import org.apache.hivemind.internal.Module;
024    import org.apache.hivemind.schema.Translator;
025    
026    /**
027     * Used to translate a set of strings to one of a number of constant values.
028     * Each input string is matched against the name of a public static field
029     * of a class.  The name of the class, and the mappings, are provided
030     * in the initializer.
031     *
032     * @author Howard Lewis Ship
033     */
034    public class EnumerationTranslator implements Translator
035    {
036        private Map _mappings;
037        private String _className;
038        private Class _class;
039    
040        /**
041         * Initialized the translator; the intitializer is the name of the class, a comma,
042         * and a series of key=value mappings from the input values to the names
043         * of the public static fields of the class.
044         */
045        public EnumerationTranslator(String initializer)
046        {
047            int commax = initializer.indexOf(',');
048    
049            _className = initializer.substring(0, commax);
050    
051            _mappings = RuleUtils.convertInitializer(initializer.substring(commax + 1));
052        }
053    
054        private synchronized Class getClass(Module contributingModule)
055        {
056            if (_class == null)
057                _class = contributingModule.resolveType(_className);
058    
059            return _class;
060        }
061    
062        public Object translate(
063            Module contributingModule,
064            Class propertyType,
065            String inputValue,
066            Location location)
067        {
068            if (HiveMind.isBlank(inputValue))
069                return null;
070    
071            Class c = getClass(contributingModule);
072    
073            String fieldName = (String) _mappings.get(inputValue);
074    
075            if (fieldName == null)
076                throw new ApplicationRuntimeException(
077                    RulesMessages.enumNotRecognized(inputValue),
078                    location,
079                    null);
080    
081            try
082            {
083                Field f = c.getField(fieldName);
084    
085                return f.get(null);
086            }
087            catch (Exception ex)
088            {
089                throw new ApplicationRuntimeException(
090                    RulesMessages.enumError(c, fieldName, ex),
091                    location,
092                    ex);
093            }
094        }
095    
096    }