/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you 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.myfaces.test.el;

import java.beans.FeatureDescriptor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.el.ELContext;
import javax.el.PropertyNotWritableException;

/**
 * {@code ELResolver} for reserved words.
 */
public class ReservedWordsELResolver extends AbstractELResolver {
    private static final Map<String, Object> VALUES;
    static {
        HashMap<String, Object> values = new HashMap<String, Object>();
        values.put("true", Boolean.TRUE);
        values.put("false", Boolean.FALSE);
        values.put("null", null);
        VALUES = Collections.unmodifiableMap(values);
    }

    private List<FeatureDescriptor> featureDescriptors;

    @Override
    public Object getValue(ELContext context, Object base, Object property) {
        if (base == null && VALUES.containsKey(property)) {
            context.setPropertyResolved(true);
            return VALUES.get(property);
        }
        return null;
    }

    @Override
    public Class<?> getType(ELContext context, Object base, Object property) {
        if (base == null && VALUES.containsKey(property)) {
            context.setPropertyResolved(true);
            Object value = VALUES.get(property);
            return value == null ? null : value.getClass();
        }
        return null;
    }

    @Override
    public void setValue(ELContext context, Object base, Object property,
        Object value) {
        if (base == null && VALUES.containsKey(property)) {
            context.setPropertyResolved(true);
            throw new PropertyNotWritableException(property.toString());
        }
    }

    @Override
    public boolean isReadOnly(ELContext context, Object base, Object property) {
        if (base == null && VALUES.containsKey(property)) {
            context.setPropertyResolved(true);
            return true;
        }
        return false;
    }

    @Override
    public synchronized Iterator<FeatureDescriptor> getFeatureDescriptors(
        ELContext context, Object base) {
        if (featureDescriptors == null) {
            featureDescriptors = new ArrayList<FeatureDescriptor>();
            for (Map.Entry<String, Object> e : VALUES.entrySet()) {
                final Class<?> type =
                    e.getValue() == null ? null : e.getValue().getClass();
                featureDescriptors.add(descriptor(e.getKey(), e.getKey(),
                    e.getKey(), false, false, true, type, true));
            }
            featureDescriptors =
                Collections.unmodifiableList(featureDescriptors);
        }
        return featureDescriptors.iterator();
    }

    @Override
    public Class<?> getCommonPropertyType(ELContext context, Object base) {
        return base == null ? String.class : null;
    }

}
