/*
This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along
with this program; if not, see http://www.gnu.org/licenses or write to the Free
Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
package com.servoy.j2db.util.docvalidator;
import java.text.DecimalFormatSymbols;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
import com.servoy.j2db.util.docvalidator.ValidatingDocument.IDocumentValidator;
/**
* @author jblok
*/
public class NumberDocumentValidator extends DocumentFilter implements ValidatingDocument.IDocumentValidator
{
private boolean allowNegativeValues = true;
private final DecimalFormatSymbols decimalFormatSymbols;
private final int maxLength;
public NumberDocumentValidator()
{
this(null, -1);
}
/**
* @param decimalFormatSymbols
*/
public NumberDocumentValidator(DecimalFormatSymbols decimalFormatSymbols, int maxLength)
{
this.decimalFormatSymbols = decimalFormatSymbols;
this.maxLength = maxLength;
}
/**
* @param maxLength
*/
public NumberDocumentValidator(int maxLength)
{
this(null, maxLength);
}
public String validateInsertString(Document document, int offs, String str, AttributeSet a) throws BadLocationException
{
return validateReplace(document, offs, 0, str, a);
}
/**
* @param ch
* @return
*/
private boolean testchar(char ch)
{
if (Character.isDigit(ch)) return true;
if (decimalFormatSymbols != null)
{
if (decimalFormatSymbols.getGroupingSeparator() == ch || decimalFormatSymbols.getPercent() == ch ||
(allowNegativeValues && decimalFormatSymbols.getMinusSign() == ch)) return true;
if ((decimalFormatSymbols.getDecimalSeparator() == ch || decimalFormatSymbols.getMonetaryDecimalSeparator() == ch)) return true;
if (decimalFormatSymbols.getCurrencySymbol() != null && decimalFormatSymbols.getCurrencySymbol().indexOf(ch) != -1) return true;
return false;
}
return ch == '.' || ch == ',' || (ch == '-' && allowNegativeValues);
}
/**
* @param b
*/
public void setAllowNegativeValues(boolean b)
{
allowNegativeValues = b;
}
public String validateReplace(Document document, int offset, int length, String str, AttributeSet attrs) throws BadLocationException
{
char[] source = str.toCharArray();
char[] result = new char[source.length];
int j = 0;
for (int i = 0; i < result.length; i++)
{
char ch = source[i];
if (testchar(ch))
{
result[j++] = ch;
}
}
if (j > 0)
{
String retString = new String(result, 0, j);
String currentTxt = document.getText(0, offset) + retString + document.getText(offset + length, document.getLength() - offset - length);
if (decimalFormatSymbols != null)
{
int index1 = currentTxt.indexOf(decimalFormatSymbols.getDecimalSeparator());
int index2 = currentTxt.lastIndexOf(decimalFormatSymbols.getDecimalSeparator());
if (index1 != index2) return ""; //$NON-NLS-1$
int index11 = currentTxt.indexOf(decimalFormatSymbols.getMonetaryDecimalSeparator());
int index22 = currentTxt.lastIndexOf(decimalFormatSymbols.getMonetaryDecimalSeparator());
if (index11 != index22) return ""; //$NON-NLS-1$
int lastGroupIndex = currentTxt.lastIndexOf(decimalFormatSymbols.getGroupingSeparator());
if (lastGroupIndex != -1)
{
if (index1 != -1 && lastGroupIndex > index1) return ""; //$NON-NLS-1$
if (index11 != -1 && lastGroupIndex > index11) return ""; //$NON-NLS-1$
}
int minusIndex = currentTxt.indexOf(decimalFormatSymbols.getMinusSign());
if (minusIndex != -1 && minusIndex != 0 && minusIndex != currentTxt.length() - 1) return ""; //$NON-NLS-1$
int currencyIndex = currentTxt.indexOf(decimalFormatSymbols.getCurrencySymbol());
if (currencyIndex != -1 && currencyIndex != 0 && !currentTxt.endsWith(decimalFormatSymbols.getCurrencySymbol())) return ""; //$NON-NLS-1$
int percentIndex = currentTxt.indexOf(decimalFormatSymbols.getPercent());
if (percentIndex != -1 && percentIndex != currentTxt.length() - 1) return ""; //$NON-NLS-1$
}
if (maxLength > 0)
{
int counter = 0;
for (int k = 0; k < currentTxt.length(); k++)
{
if (Character.isDigit(currentTxt.charAt(k)))
{
counter++;
}
}
if (counter > maxLength) return ""; //$NON-NLS-1$
}
return retString;
}
return ""; //$NON-NLS-1$
}
/**
* @see javax.swing.text.DocumentFilter#insertString(javax.swing.text.DocumentFilter.FilterBypass, int, java.lang.String, javax.swing.text.AttributeSet)
*/
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attrs) throws BadLocationException
{
String test = validateReplace(fb.getDocument(), offset, 0, text, attrs);
super.insertString(fb, offset, test, attrs);
}
/**
* @see javax.swing.text.DocumentFilter#replace(javax.swing.text.DocumentFilter.FilterBypass, int, int, java.lang.String, javax.swing.text.AttributeSet)
*/
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException
{
String test = validateReplace(fb.getDocument(), offset, length, text, attrs);
super.replace(fb, offset, length, test, attrs);
}
}