/** * Copyright (C) 2015 Valkyrie RCP * * Licensed 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.valkyriercp.binding.format.support; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.valkyriercp.binding.format.Formatter; import org.valkyriercp.binding.format.InvalidFormatException; import java.text.ParseException; /** * Abstract base class for all formatters. * * @author Keith Donald */ public abstract class AbstractFormatter implements Formatter { /** * Does this formatter allow empty values? */ private boolean allowEmpty = true; /** * Constructs a formatter. */ protected AbstractFormatter() { } /** * Constructs a formatter. * @param allowEmpty allow formatting of empty (null or blank) values? */ protected AbstractFormatter(boolean allowEmpty) { this.allowEmpty = allowEmpty; } /** * Allow formatting of empty (null or blank) values? */ public boolean isAllowEmpty() { return allowEmpty; } public final String formatValue(Object value) { if (allowEmpty && isEmpty(value)) { return getEmptyFormattedValue(); } Assert.isTrue(!isEmpty(value), "Object to format cannot be empty"); return doFormatValue(value); } /** * Template method subclasses should override to encapsulate formatting logic. * @param value the value to format * @return the formatted string representation */ protected abstract String doFormatValue(Object value); /** * Returns the formatted form of an empty value. Default implementation just returns the empty string. */ protected String getEmptyFormattedValue() { return ""; } public final Object parseValue(String formattedString, Class targetClass) throws InvalidFormatException { try { if (allowEmpty && isEmpty(formattedString)) { return getEmptyValue(); } return doParseValue(formattedString, targetClass); } catch (ParseException ex) { throw new InvalidFormatException(formattedString, getExpectedFormat(targetClass), ex); } } /** * Template method subclasses should override to encapsulate parsing logic. * @param formattedString the formatted string to parse * @return the parsed value * @throws InvalidFormatException an exception occured parsing * @throws ParseException when parse exceptions occur */ protected abstract Object doParseValue(String formattedString, Class targetClass) throws InvalidFormatException, ParseException; /** * Returns the empty value (resulting from parsing an empty input string). This default implementation just returns * null. */ protected Object getEmptyValue() { return null; } /** * Returns the expected string format for the given target class. The default implementation just returns null. */ protected String getExpectedFormat(Class targetClass) { return null; } /** * Is given object <i>empty</i> (null or empty string)? */ protected boolean isEmpty(Object o) { if (o == null) { return true; } else if (o instanceof String) { return !StringUtils.hasText((String) o); } else { return false; } } }