/* * OpenClinica is distributed under the GNU Lesser General Public License (GNU * LGPL). * * For details see: http://www.openclinica.org/license copyright 2003-2010 Akaza * Research * */ package org.akaza.openclinica.bean.extract; import java.util.TreeSet; /** * Validate if a SPSS variable name is valid. * <p> * A valid SPSS variable name should follow the rule that * <li> it can be up to eight characters long * <li> it must begin with a letter * <li> it cannot end with a period * <li> its remaining characters can be any letter, any digit, a period or the * symbols @, #, _, or $ * <li> it should be avoided of ending with an underscore * <li> it can not be any reserved keyword, i.e., ALL, AND, BY, EQ, GE, * GT, LE, LT, NE, NOT, OR, TO, WITH. * * <br> * <p> * Rules for creating a valid SPSS variable name: * <li> Replace any invalid character with the symbol # * <li> If the first character is not a letter, letter V will be used as first * letter * <li> If the last character is a period or underscore, it will replaced by # * <li> If a name is longer than 64 characters, it will be truncated to 64 * characters. If it results in non-unique name in a data file, sequential * numbers are used to replace its letters at the end. By default, the size of * sequential numbers is 3. * <li> If a reserved keyword has been used as a variable name, squential * numbers are apended to its end. * * @auther ywang */ @Deprecated public class SPSSVariableNameValidator extends NameValidator { private final String[] reservedKeywords = { "all", "and", "by", "eq", "ge", "gt", "le", "lt", "ne", "not", "or", "to", "with" }; private char replacingChar = '#'; private char replacingFirstChar = 'V'; private int nameMaxLength = 64; /** * Given a variable name, this methods returns a valid SPSS variable name * and it guarantees the uniqueness of this name * * @param variableName * String * @return String */ @Override public String getValidName(String variableName) { int maxValue = this.computeMaxValue(variableName.length()); // if variableName is null, automatically generate if (variableName == null || variableName.trim().length() == 0) { return getNextSequentialString(maxValue); } int i; String temp = variableName.trim(); // first, check if reserved keywords have been used. if (isReservedKeyword(temp)) { String s = temp + this.getNextSequentialString(maxValue); return s; } else { // variable name is not reserved keyword // get all chars from the string first and get at most nameMaxLength // characters char c[] = temp.length() > this.nameMaxLength ? temp.substring(0, this.nameMaxLength).toCharArray() : temp.toCharArray(); int len = c.length; // replacing every invalid character with the replacingChar for (i = 0; i < len; ++i) { if (!isValid(c[i])) { c[i] = this.replacingChar; } } // if the first one is not a letter if (!(c[0] >= 'a' && c[0] <= 'z' || c[0] >= 'A' && c[0] <= 'Z')) { // if there is already 8 characters if (len >= this.nameMaxLength) { for (i = len - 1; i >= 1; --i) { c[i] = c[i - 1]; } c[0] = this.replacingFirstChar; } else { char cc[] = new char[len + 1]; cc[0] = this.replacingFirstChar; for (i = 1; i < cc.length; ++i) { cc[i] = c[i - 1]; } c = cc; } } // if the last one is "." or "_" if (c[len - 1] == '.' || c[len - 1] == '_') { c[len - 1] = this.replacingChar; } String s = new String(c); String s2 = s; int mysize = this.nameMaxLength - digitSize; // if not unique while (uniqueNameTable.contains(s2)) { if (s.length() > mysize) { s2 = s.substring(0, mysize) + this.getNextSequentialString(maxValue); } else { s2 = s + this.getNextSequentialString(maxValue); } } uniqueNameTable.add(s2); return s2; } } @Override protected boolean isValid(char c) { return c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '.' || c == '@' || c == '#' || c == '_' || c == '$'; } /** * * @return String */ @Override public String getNextSequentialString(int maxValue) { if(this.sequential>=maxValue) { System.exit(1); } String s = "" + this.sequential; int len = s.length(); if(len<this.digitSize) { for (int i = len; i < this.digitSize; ++i) { s = "0" + s; } } this.sequential ++; return s; } private int computeMaxValue(int nameLength) { int len = nameLength > this.nameMaxLength ? this.digitSize : this.nameMaxLength - nameLength; len = len < this.digitSize ? this.digitSize : len; int maxValue = len > 9 ? (int) Math.pow(10, 9) : (int) Math.pow(10, len); return maxValue; } private boolean isReservedKeyword(String s) { // The maxium length of reserved keywords are 4 if (s.length() < 5) { for (int i = 0; i < this.reservedKeywords.length; ++i) { if (s.equalsIgnoreCase(this.reservedKeywords[i])) { return true; } } } return false; } @Override public char getReplacingChar() { return replacingChar; } @Override public void setReplacingChar(char replacingChar) { this.replacingChar = replacingChar; } public int getNameMaxLength() { return nameMaxLength; } public void setNameMaxLength(int nameMaxLength) { this.nameMaxLength = nameMaxLength; } public String[] getReservedKeywords() { return reservedKeywords; } public void setReplacingFirstChar(char fc) { this.replacingFirstChar = fc; } public char getReplacingFirstChar() { return this.replacingFirstChar; } }