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    
020    package org.apache.isis.core.progmodel.facets.value.bigdecimal;
021    
022    import java.math.BigDecimal;
023    import java.text.DecimalFormat;
024    import java.text.NumberFormat;
025    import java.util.Locale;
026    
027    import org.apache.isis.applib.adapters.EncoderDecoder;
028    import org.apache.isis.applib.adapters.Parser;
029    import org.apache.isis.applib.profiles.Localization;
030    import org.apache.isis.core.commons.config.IsisConfiguration;
031    import org.apache.isis.core.commons.exceptions.IsisException;
032    import org.apache.isis.core.metamodel.facetapi.Facet;
033    import org.apache.isis.core.metamodel.facetapi.FacetHolder;
034    import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
035    import org.apache.isis.core.progmodel.facets.object.value.ValueSemanticsProviderAndFacetAbstract;
036    import org.apache.isis.core.progmodel.facets.object.value.ValueSemanticsProviderContext;
037    
038    public class BigDecimalValueSemanticsProvider extends ValueSemanticsProviderAndFacetAbstract<BigDecimal> implements
039        BigDecimalValueFacet {
040    
041        private static Class<? extends Facet> type() {
042            return BigDecimalValueFacet.class;
043        }
044    
045        private static final int TYPICAL_LENGTH = 19;
046        private static final boolean IMMUTABLE = true;
047        private static final boolean EQUAL_BY_CONTENT = true;
048        private static final BigDecimal DEFAULT_VALUE = new BigDecimal(0);
049    
050        private final NumberFormat format;
051    
052        /**
053         * Required because implementation of {@link Parser} and {@link EncoderDecoder}.
054         */
055        public BigDecimalValueSemanticsProvider() {
056            this(null, null, null);
057        }
058    
059        public BigDecimalValueSemanticsProvider(final FacetHolder holder, final IsisConfiguration configuration,
060            final ValueSemanticsProviderContext context) {
061            super(type(), holder, BigDecimal.class, TYPICAL_LENGTH, IMMUTABLE, EQUAL_BY_CONTENT, DEFAULT_VALUE,
062                configuration, context);
063            format = determineNumberFormat("value.format.decimal");
064        }
065    
066        public void setLocale(final Locale l) {
067            // TODO Auto-generated method stub
068    
069        }
070    
071        // //////////////////////////////////////////////////////////////////
072        // Parser
073        // //////////////////////////////////////////////////////////////////
074    
075        @Override
076        protected BigDecimal doParse(final Object context, final String entry) {
077            try {
078                return new BigDecimal(entry);
079            } catch (final NumberFormatException e) {
080                throw new TextEntryParseException("Not an decimal " + entry, e);
081            }
082        }
083    
084        @Override
085        public String titleString(final Object object, final Localization localization) {
086            return titleString(format, object);
087        }
088    
089        @Override
090        public String titleStringWithMask(final Object value, final String usingMask) {
091            return titleString(new DecimalFormat(usingMask), value);
092        }
093    
094        // //////////////////////////////////////////////////////////////////
095        // EncoderDecoder
096        // //////////////////////////////////////////////////////////////////
097    
098        @Override
099        protected String doEncode(final Object object) {
100            // for dotnet compatibility - toString pre 1.3 was equivalent to toPlainString later.
101            try {
102                final Class<?> type = object.getClass();
103                try {
104                    return (String) type.getMethod("toPlainString", (Class[]) null).invoke(object, (Object[]) null);
105                } catch (final NoSuchMethodException nsm) {
106                    return (String) type.getMethod("toString", (Class[]) null).invoke(object, (Object[]) null);
107                }
108            } catch (final Exception e) {
109                throw new IsisException(e);
110            }
111    
112        }
113    
114        @Override
115        protected BigDecimal doRestore(final String data) {
116            return new BigDecimal(data);
117        }
118    
119        // /////// toString ///////
120    
121        @Override
122        public String toString() {
123            return "BigDecimalValueSemanticsProvider: " + format;
124        }
125    
126    }