blob: a9c90d250998b36a15c683a1fbcb121c86018704 [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.openjpa.lib.identifier;
import java.util.HashSet;
import java.util.Set;
import org.apache.openjpa.lib.util.StringUtil;
/**
* The standard identifier rule. Rules are used for specific configuration
* of identifier types. For example. A rule could be used to indicate that
* an identifier type should not be delimited or has a max length of 255
* characters.
*
*/
public class IdentifierRule {
public static final Set<String> EMPTY_SET = new HashSet<>(0);
public static final String DEFAULT_RULE = "default";
public static char UNDERSCORE = '_';
private String _name;
private int _maxLength = 128;
private boolean _nullable = false;
private boolean _allowTruncation = false;
private boolean _allowCompaction = true;
private boolean _canDelimit = true;
private boolean _mustDelimit = false;
private boolean _mustBeginWithLetter = true;
private boolean _onlyLettersDigitsUnderscores = true;
private String _specialCharacters = "";
private Set<String> _reservedWords = null;
private boolean _delimitReservedWords = false;
private String _wildcard = "%";
public void setName(String name) {
_name = name;
}
public String getName() {
return _name;
}
public void setMaxLength(int maxLength) {
_maxLength = maxLength;
}
public int getMaxLength() {
return _maxLength;
}
public void setAllowTruncation(boolean allowTruncation) {
_allowTruncation = allowTruncation;
}
public boolean isAllowTruncation() {
return _allowTruncation;
}
public void setNullable(boolean nullable) {
_nullable = nullable;
}
public boolean isNullable() {
return _nullable;
}
public void setAllowCompaction(boolean allowCompaction) {
_allowCompaction = allowCompaction;
}
public boolean getAllowCompaction() {
return _allowCompaction;
}
public void setCanDelimit(boolean canDelimit) {
_canDelimit = canDelimit;
}
public boolean getCanDelimit() {
return _canDelimit;
}
public void setMustDelimit(boolean mustDelimit) {
_mustDelimit = mustDelimit;
}
public boolean getMustDelimit() {
return _mustDelimit;
}
public void setMustBeginWithLetter(boolean mustBeginWithLetter) {
_mustBeginWithLetter = mustBeginWithLetter;
}
public boolean isMustBeginWithLetter() {
return _mustBeginWithLetter;
}
public void setOnlyLettersDigitsUnderscores(boolean onlyLettersDigitsUnderscores) {
_onlyLettersDigitsUnderscores = onlyLettersDigitsUnderscores;
}
public boolean isOnlyLettersDigitsUnderscores() {
return _onlyLettersDigitsUnderscores;
}
public void setReservedWords(Set<String> reservedWords) {
_reservedWords = reservedWords;
}
public Set<String> getReservedWords() {
if (_reservedWords == null) {
_reservedWords = new HashSet<>();
}
return _reservedWords;
}
public void setSpecialCharacters(String specialCharacters) {
_specialCharacters = specialCharacters;
}
public String getSpecialCharacters() {
return _specialCharacters;
}
public void setDelimitReservedWords(boolean delimitReservedWords) {
_delimitReservedWords = delimitReservedWords;
}
public boolean getDelimitReservedWords() {
return _delimitReservedWords;
}
/**
* SQL identifier rules:
* 1) Can be up to 128 characters long
* 2) Must begin with a letter
* 3) Can contain letters, digits, and underscores
* 4) Can't contain spaces or special characters such as #, $, &, %, or
* punctuation.
* 5) Can't be reserved words
*/
public boolean requiresDelimiters(String identifier) {
// Do not delimit single valued wildcards or "?" or names that have method-type
// signatures (ex. getValue()). These are considered special values in OpenJPA
// and should not be delimited.
if (_wildcard.equals(identifier) || "?".equals(identifier) ||
identifier.endsWith("()")) {
return false;
}
if (getMustDelimit()) {
return true;
}
// Assert identifier begins with a letter
char[] chars = identifier.toCharArray();
if (isMustBeginWithLetter()) {
if (!Character.isJavaIdentifierStart(chars[0])) {
return true;
}
}
// Iterate through chars, asserting delimiting rules
for (char ch : chars) {
if (isOnlyLettersDigitsUnderscores()) {
if (!Character.isJavaIdentifierPart(ch) && !(ch == UNDERSCORE)) {
return true;
}
}
// Look for special characters
if (StringUtil.contains(getSpecialCharacters(), ch)) {
return true;
}
}
// Finally, look for reserved words
if (getDelimitReservedWords()) {
if (isReservedWord(identifier)) {
return true;
}
}
return false;
}
public boolean isReservedWord(String identifier) {
return _reservedWords.contains(identifier);
}
}