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 java.lang.reflect.Field;
018import java.util.Map;
019
020import org.apache.hivemind.ApplicationRuntimeException;
021import org.apache.hivemind.HiveMind;
022import org.apache.hivemind.Location;
023import org.apache.hivemind.internal.Module;
024import 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 */
034public 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}