001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.progmodel.facets.object.choices.enums;
021
022import org.apache.isis.applib.adapters.EncoderDecoder;
023import org.apache.isis.applib.adapters.Parser;
024import org.apache.isis.applib.profiles.Localization;
025import org.apache.isis.core.commons.config.IsisConfiguration;
026import org.apache.isis.core.metamodel.facetapi.Facet;
027import org.apache.isis.core.metamodel.facetapi.FacetHolder;
028import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
029import org.apache.isis.core.progmodel.facets.object.value.ValueSemanticsProviderAndFacetAbstract;
030import org.apache.isis.core.progmodel.facets.object.value.ValueSemanticsProviderContext;
031
032public class EnumValueSemanticsProvider<T extends Enum<T>> extends ValueSemanticsProviderAndFacetAbstract<T> implements EnumFacet {
033
034    private static Class<? extends Facet> type() {
035        return EnumFacet.class;
036    }
037    
038    private static <T> T defaultFor(final Class<T> adaptedClass) {
039        return adaptedClass.getEnumConstants()[0];
040    }
041
042    private static <T extends Enum<T>> int typicalLengthFor(final Class<T> adaptedClass) {
043        int max = Integer.MIN_VALUE;
044        for(T e: adaptedClass.getEnumConstants()) {
045            max = Math.max(max, e.name().length());
046        }
047        return max;
048    }
049    
050    /**
051     * Required because {@link Parser} and {@link EncoderDecoder}.
052     */
053    public EnumValueSemanticsProvider() {
054        this(null, null, null, null);
055    }
056
057    public EnumValueSemanticsProvider(final FacetHolder holder, final Class<T> adaptedClass, final IsisConfiguration configuration, final ValueSemanticsProviderContext context) {
058        super(
059                type(), holder,  adaptedClass, 
060                typicalLengthFor(adaptedClass), 
061                Immutability.IMMUTABLE, 
062                EqualByContent.HONOURED, 
063                defaultFor(adaptedClass), 
064                configuration, context);
065    }
066
067    @Override
068    protected T doParse(final Object context, final String entry) {
069        final T[] enumConstants = getAdaptedClass().getEnumConstants();
070        for (final T enumConstant : enumConstants) {
071            if (enumConstant.toString().equals(entry)) {
072                return enumConstant;
073            }
074        }
075        throw new TextEntryParseException("Unknown enum constant '" + entry + "'");
076    }
077
078    @Override
079    protected String doEncode(final Object object) {
080        return titleString(object, null);
081    }
082
083    @Override
084    protected T doRestore(final String data) {
085        return doParse(null, data);
086    }
087
088    @Override
089    protected String titleString(final Object object, final Localization localization) {
090        return object.toString();
091    }
092
093    @Override
094    public String titleStringWithMask(final Object value, final String usingMask) {
095        return titleString(value, null);
096    }
097
098}