/*******************************************************************************
* Copyright (c) 2007, 2014 compeople AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* compeople AG - initial API and implementation
*******************************************************************************/
package org.eclipse.riena.ui.ridgets.validation;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.riena.core.util.ArraysUtil;
import org.eclipse.riena.core.util.PropertiesUtils;
/**
*
*/
public class MaxNumberLength extends MaxLength {
private DecimalFormatSymbols symbols;
private Locale locale;
/**
* Creates a MexLength rule for numbers.
*/
public MaxNumberLength() {
this(0, Locale.getDefault());
}
/**
* Creates a MexLength rule for numbers.
*
* @param length
* The maximum number of characters excluding a leading minus
* sign.
*/
public MaxNumberLength(final int length) {
this(length, Locale.getDefault());
}
/**
* Creates a MexLength rule for numbers.
*
* @param length
* The maximum number of characters excluding a leading minus
* sign.
*/
public MaxNumberLength(final int length, final Locale locale) {
super(length);
this.locale = locale;
}
/**
* @see org.eclipse.riena.ui.internal.ridgets.validation.MaxLength#validate(java.lang.Object)
*/
@Override
public IStatus validate(final Object value) {
if (value == null) {
return ValidationRuleStatus.ok();
}
if (value instanceof String) {
String string = Utils.removeWhitespaceAndGroupingCharacter((String) value, getSymbols()
.getGroupingSeparator());
if (string.length() > 0) {
if (string.charAt(0) == getSymbols().getMinusSign()) {
string = string.substring(1);
} else if (string.charAt(string.length() - 1) == getSymbols().getMinusSign()) {
// for Arab locales
string = string.substring(0, string.length() - 1);
}
}
return super.validate(string);
}
throw new ValidationFailure(getClass().getName() + " can only validate objects of type String."); //$NON-NLS-1$
}
/**
* This method is called on a newly constructed extension for validation.
* After creating a new instance of {@code ValidInteger} this method is
* called to initialize the instance. The argument for initialization are in
* the parameter {@code data}. Is the data a string the arguments are
* separated with ','. The order of the arguments in data is equivalent to
* the order of the parameters of one of the constructors.<br>
* If data has more than one argument. The last arguments are used to set
* the Local for this validator.
*
*
* @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
* java.lang.String, java.lang.Object)
* @see org.eclipse.riena.ui.ridgets.validation.ValidDecimal#setLocale(java.lang.String[])
*/
@Override
public void setInitializationData(final IConfigurationElement config, final String propertyName, final Object data)
throws CoreException {
if (data instanceof String) {
final String[] args = PropertiesUtils.asArray(data);
int localStart = 0;
if (args.length > 0) {
this.maxLength = Integer.parseInt(args[0]);
localStart++;
}
if (args.length > localStart) {
final String[] localArgs = ArraysUtil.copyRange(args, localStart, args.length);
setLocal(localArgs);
}
}
}
/**
* Creates and sets the Local for this validator.
*
* @param localArgs
* language, country, variant
*/
protected void setLocal(final String[] localArgs) {
if (localArgs.length > 0) {
final String language = localArgs[0];
String country = ""; //$NON-NLS-1$
String variant = ""; //$NON-NLS-1$
if (localArgs.length > 1) {
country = localArgs[1];
}
if (localArgs.length > 2) {
variant = localArgs[2];
}
setLocale(new Locale(language, country, variant));
}
}
/**
* Gets the s DecimalFormatSymbols of this rule's {@link #format}. Changes
* on the symbols will change the rule's format accordingly. As
* DecimalFormat is not thread safe, changes to the symbols must be properly
* synchronized with accessing the format.
*
* @see #getFormat()
*/
protected DecimalFormatSymbols getSymbols() {
if (symbols == null) {
final DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(locale);
symbols = format.getDecimalFormatSymbols();
}
return symbols;
}
private void setLocale(final Locale locale) {
this.locale = locale;
}
}