at.spardat.enterprise.fmt.AStringFmtRange Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* 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:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
// @(#) $Id: AStringFmtRange.java 2093 2007-11-28 14:23:36Z s3460 $
package at.spardat.enterprise.fmt;
/**
* This class defines a formatter which accepts characters from character ranges. Since
* the regexp implementation is not yet available in JDKs less than 1.4, we use a simple
* implementation here.
*
* Character ranges are specified as string. The characters in the string are either
* the allowed character themselves, or lower and upper character separated by an hypen.
* Note that for these ranges to work you must know the Unicode table and what
* characters are included between particular upper and lower characters.
*
* Some examples:
*
* ABCDEF denotes the characters A through F
* A-F the same as before
* a-fA-F denotes the character set abcdefABCDEF
* 1a-f denotes 1abcdef
* a-zA-Z0-9 denotes the letters a through z, case insensitive and digits
* ]- denotes the character '-'. A ']' is used to escape the '-'.
* ]] denotes the character ']'. A ']' is used to escape itself.
* ]t horizontal tab, '\u0009'
* ]n new line, '\u000A'
* ]f form feed, '\u000C'
* ]r carriage return, '\u000D'
*/
public class AStringFmtRange extends AStringFmt {
/**
* Range string denoting the digits 0-9
*/
public static final String DIGITS = "0-9";
/**
* Range string denoting characters which may be safely transmitted over INA/ACNS to z/OS
*/
public static final String INA = " -{}~????????";
// the escape character
private static final char ESC = ']';
// the number of filled slots in the arrays lower_ and upper_
private int numRanges_;
// the lower bounds of the character ranges
private char [] lower_;
// the upper bounds of the ranges
private char [] upper_;
/**
* Constructs a String range formatter.
*
* @param maxLen the maximum length; -1 if unlimited;
* @param range a range specification as defined in the class description above.
*/
public AStringFmtRange (int maxLen, String range) {
super (maxLen);
if (range == null) throw new IllegalArgumentException ();
// make space for the upper and lower char arrays
lower_ = new char[range.length()];
upper_ = new char[range.length()];
// parse range
int index = 0;
while (index < range.length()) {
char ch1 = range.charAt(index);
char ch2 = index+1 < range.length() ? range.charAt(index+1) : 0;
if (ch1 == ESC) {
// our escape character
if (ch2 == ESC) {
// and the next is also an escape
index += 2;
insertBound (ESC, ESC);
continue;
} else if (ch2 == '-') {
// and the next is a '-', then it is an escaped '-'
index += 2;
insertBound ('-', '-');
continue;
} else if (ch2 == 't') {
index += 2; insertBound ('\t', '\t'); continue;
} else if (ch2 == 'n') {
index += 2; insertBound ('\n', '\n'); continue;
} else if (ch2 == 'f') {
index += 2; insertBound ('\f', '\f'); continue;
} else if (ch2 == 'r') {
index += 2; insertBound ('\r', '\r'); continue;
}
// nothing escaped; range is the escape char
index++;
insertBound (ESC, ESC);
continue;
}
// the character isn't an escape character
// we look for a character range
if (ch2 == '-') {
// looks like a range, but there must be a third character
if (index+2 < range.length()) {
// definitely a range
insertBound (ch1, range.charAt(index+2));
index += 3;
continue;
}
}
// what remains is simply a single character range
insertBound (ch1, ch1);
index++;
}
}
/**
* Constructs a String range formatter.
*
* @param maxLen the maximum length; -1 if unlimited;
* @param range a range specification as defined in the class description above.
* @param style may be MANDATORY
*/
public AStringFmtRange (int maxLen, String range, int style) {
this (maxLen, range);
style_ = style;
}
/**
* @see at.spardat.enterprise.fmt.IFmt#isLegalExternalChar(char)
*/
public boolean isLegalExternalChar (char aChar) {
// look for a matching range
for (int i=0; i= lower_[i] && aChar <= upper_[i]) return true;
}
return false;
}
/**
* @see at.spardat.enterprise.fmt.IFmt#isLegalInternal(String)
*/
public boolean isLegalInternal (String internal) {
if (internal == null || internal.length() == 0) return true;
if (!super.isLegalInternal (internal)) return false;
for (int i=internal.length()-1; i>=0; i--) {
// we can use isLegalExternalChar, since external and internal must obey the same restrictions
if (!isLegalExternalChar (internal.charAt(i))) return false;
}
return true;
}
/**
* @see at.spardat.enterprise.fmt.IFmt#parse(String)
*/
public String parse (String external) throws FmtParseException {
super.parse (external); // throws an exception on violations of superclass restrictions
if (external == null || external.length() == 0) return "";
// iterate over the ranges
for (int i=0, len=external.length(); i