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.percentage;
021
022 import java.text.DecimalFormat;
023 import java.text.NumberFormat;
024 import java.text.ParseException;
025
026 import org.apache.isis.applib.adapters.EncoderDecoder;
027 import org.apache.isis.applib.adapters.Parser;
028 import org.apache.isis.applib.profiles.Localization;
029 import org.apache.isis.applib.value.Percentage;
030 import org.apache.isis.core.commons.config.ConfigurationConstants;
031 import org.apache.isis.core.commons.config.IsisConfiguration;
032 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
033 import org.apache.isis.core.metamodel.facetapi.Facet;
034 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
035 import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
036 import org.apache.isis.core.progmodel.facets.object.value.ValueSemanticsProviderAndFacetAbstract;
037 import org.apache.isis.core.progmodel.facets.object.value.ValueSemanticsProviderContext;
038 import org.apache.isis.core.progmodel.facets.value.floats.FloatingPointValueFacet;
039
040 public class PercentageValueSemanticsProvider extends ValueSemanticsProviderAndFacetAbstract<Percentage> implements
041 FloatingPointValueFacet {
042
043 private static final NumberFormat PERCENTAGE_FORMAT = NumberFormat.getPercentInstance();
044 private static final NumberFormat DECIMAL_FORMAT = NumberFormat.getNumberInstance();
045
046 private static final Percentage DEFAULT_VALUE = new Percentage(0.0f);
047 private static final int TYPICAL_LENGTH = 12;
048 private static final boolean IMMUTABLE = true;
049 private static final boolean EQUAL_BY_CONTENT = true;
050
051 public static Class<? extends Facet> type() {
052 return FloatingPointValueFacet.class;
053 }
054
055 private NumberFormat format = PERCENTAGE_FORMAT;
056
057 /**
058 * Required because implementation of {@link Parser} and {@link EncoderDecoder}.
059 */
060 public PercentageValueSemanticsProvider() {
061 this(null, null, null);
062 }
063
064 public PercentageValueSemanticsProvider(final FacetHolder holder, final IsisConfiguration configuration,
065 final ValueSemanticsProviderContext context) {
066 super(type(), holder, Percentage.class, TYPICAL_LENGTH, IMMUTABLE, EQUAL_BY_CONTENT, DEFAULT_VALUE,
067 configuration, context);
068
069 final String formatRequired = configuration.getString(ConfigurationConstants.ROOT + "value.format.percentage");
070 if (formatRequired == null) {
071 format = PERCENTAGE_FORMAT;
072 } else {
073 format = new DecimalFormat(formatRequired);
074 }
075 }
076
077 // //////////////////////////////////////////////////////////////////
078 // Parser
079 // //////////////////////////////////////////////////////////////////
080
081 @Override
082 protected Percentage doParse(final Object context, final String text) {
083 try {
084 return new Percentage(new Float(format.parse(text).floatValue()));
085 } catch (final ParseException e) {
086 try {
087 return new Percentage(asFloat(text));
088 } catch (final ParseException ee) {
089 throw new TextEntryParseException("Not a number " + text, ee);
090 }
091 }
092 }
093
094 private Float asFloat(final String text) throws ParseException {
095 return new Float(DECIMAL_FORMAT.parse(text).floatValue());
096 }
097
098 @Override
099 public String titleString(final Object value, final Localization localization) {
100 return titleString(format, value);
101 }
102
103 private String titleString(final NumberFormat formatter, final Object value) {
104 return value == null ? "" : format.format(((Percentage) value).floatValue());
105 }
106
107 @Override
108 public String titleStringWithMask(final Object value, final String usingMask) {
109 return titleString(new DecimalFormat(usingMask), value);
110 }
111
112 // //////////////////////////////////////////////////////////////////
113 // EncoderDecoder
114 // //////////////////////////////////////////////////////////////////
115
116 @Override
117 protected String doEncode(final Object object) {
118 final Percentage per = (Percentage) object;
119 return String.valueOf(per.floatValue());
120 }
121
122 @Override
123 protected Percentage doRestore(final String data) {
124 return new Percentage(Float.valueOf(data).floatValue());
125 }
126
127 // //////////////////////////////////////////////////////////////////
128 // FloatingPointValueFacet
129 // //////////////////////////////////////////////////////////////////
130
131 @Override
132 public Float floatValue(final ObjectAdapter object) {
133 final Percentage per = (Percentage) object.getObject();
134 return new Float(per.floatValue());
135 }
136
137 @Override
138 public ObjectAdapter createValue(final Float value) {
139 return getAdapterMap().adapterFor(value);
140 }
141
142 // //////////////////////////////////////////////////////////////////
143 // PropertyDefaultFacet
144 // //////////////////////////////////////////////////////////////////
145
146 public Object getDefault(final ObjectAdapter inObject) {
147 return Float.valueOf(0.0f);
148 }
149
150 // //// toString ////////////////////////////////////////////////////
151
152 @Override
153 public String toString() {
154 return "PercentageValueSemanticsProvider: " + format;
155 }
156
157 }