blob: 27717f82252c858e0512c5c3deeb31018cff7362 [file] [log] [blame]
/*
* 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.wicket.util.convert;
import java.text.ParseException;
import java.util.Locale;
import javax.swing.text.MaskFormatter;
import org.apache.wicket.util.lang.Args;
/**
* A converter that takes a mask into account. It is specifically meant for overrides on individual
* components, that provide their own converter by returning it from
* {@code Component#getConverter(Class)}. It uses an instance of {@link MaskFormatter} to delegate
* the masking and unmasking to.
* <p>
* The following characters can be specified (adopted from the MaskFormatter documentation):
*
* <table border=1 summary="Valid characters and their descriptions">
* <tr>
* <th>Character&nbsp;</th>
* <th>
* <p align="left">
* Description
* </p>
* </th>
* </tr>
* <tr>
* <td>#</td>
* <td>Any valid number, uses <code>Character.isDigit</code>.</td>
* </tr>
* <tr>
* <td>'</td>
* <td>Escape character, used to escape any of the special formatting characters.</td>
* </tr>
* <tr>
* <td>U</td>
* <td>Any character (<code>Character.isLetter</code>). All lowercase letters are mapped to upper
* case.</td>
* </tr>
* <tr>
* <td>L</td>
* <td>Any character (<code>Character.isLetter</code>). All upper case letters are mapped to lower
* case.</td>
* </tr>
* <tr>
* <td>A</td>
* <td>Any character or number (<code>Character.isLetter</code> or <code>Character.isDigit</code>)</td>
* </tr>
* <tr>
* <td>?</td>
* <td>Any character (<code>Character.isLetter</code>).</td>
* </tr>
* <tr>
* <td></td>
* <td>Anything.</td>
* </tr>
* <tr>
* <td>H</td>
* <td>Any hex character (0-9, a-f or A-F).</td>
* </tr>
* </table>
*
* <p>
* Typically characters correspond to one char, but in certain languages this is not the case. The
* mask is on a per character basis, and will thus adjust to fit as many chars as are needed.
* </p>
*
* @see MaskFormatter
*
* @author Eelco Hillenius
* @param <C>
*/
public class MaskConverter<C> implements IConverter<C>
{
private static final long serialVersionUID = 1L;
/** Object that knows all about masks. */
private final MaskFormatter maskFormatter;
/**
* Construct.
*
* @param maskFormatter
* The mask formatter to use for masking and unmasking values
*/
public MaskConverter(final MaskFormatter maskFormatter)
{
Args.notNull(maskFormatter, "maskFormatter");
this.maskFormatter = maskFormatter;
}
/**
* Construct; converts to Strings.
*
* @param mask
* The mask to use for this converter instance
* @see MaskFormatter
*/
public MaskConverter(final String mask)
{
this(mask, String.class);
}
/**
* Construct.
*
* @param mask
* The mask to use for this converter instance
* @param type
* The type to convert string values to.
* @see MaskFormatter
*/
public MaskConverter(final String mask, final Class<?> type)
{
try
{
maskFormatter = new MaskFormatter(mask);
maskFormatter.setValueClass(type);
maskFormatter.setAllowsInvalid(true);
maskFormatter.setValueContainsLiteralCharacters(true);
}
catch (ParseException e)
{
throw new RuntimeException(e);
}
}
/**
* Converts a string to an object using {@link MaskFormatter#stringToValue(String)}.
*/
@Override
@SuppressWarnings("unchecked")
public C convertToObject(final String value, final Locale locale)
{
try
{
return (C)maskFormatter.stringToValue(value);
}
catch (ParseException e)
{
throw new ConversionException(e);
}
}
/**
* Converts the value to a string using {@link MaskFormatter#valueToString(Object)}.
*/
@Override
public String convertToString(final C value, final Locale locale)
{
try
{
return maskFormatter.valueToString(value);
}
catch (ParseException e)
{
throw new ConversionException(e);
}
}
}