This is an automated email from the ASF dual-hosted git repository. rec pushed a commit to branch feature/369-Move-isTypeName-and-isFeatureName-to-public-API in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git
commit d0025d2c1ee05f717edf281d1abad987a3d4d05f Author: Richard Eckart de Castilho <r...@apache.org> AuthorDate: Sun Mar 24 16:40:01 2024 +0100 Issue #369: Move isTypeName and isFeatureName to public API - Moved the two methods to the public TypeSystemUtil class - Deprecate them in the old place and mark them for removal in next major version --- .../org/apache/uima/cas/impl/TypeSystemUtils.java | 83 +++++++++------------- .../java/org/apache/uima/util/TypeSystemUtil.java | 73 +++++++++++++++++++ 2 files changed, 108 insertions(+), 48 deletions(-) diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemUtils.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemUtils.java index 35070e247..bde4ade3a 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemUtils.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemUtils.java @@ -21,10 +21,10 @@ package org.apache.uima.cas.impl; import java.util.ArrayDeque; import java.util.Deque; import java.util.List; -import java.util.StringTokenizer; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; +import org.apache.uima.util.TypeSystemUtil; /** * Type Utilities - all static, so class is abstract to prevent creation Used by Feature Path @@ -233,40 +233,43 @@ public abstract class TypeSystemUtils { public void setErrorPosition(int errorPosition) { this.errorPosition = errorPosition; } - } + /** + * @deprecated Use {@link TypeSystemUtil#isFeatureName} instead + */ + @SuppressWarnings("javadoc") + @Deprecated public static boolean isIdentifier(String s) { - if (s == null) { - return false; - } - final int len = s.length(); - if (len == 0) { - return false; - } - int pos = 0; - // Check that the first character is a letter. - if (!isIdentifierStart(s.charAt(pos))) { - return false; - } - ++pos; - while (pos < len) { - if (!isIdentifierChar(s.charAt(pos))) { - return false; - } - ++pos; - } - return true; + return TypeSystemUtil.isFeatureName(s); } + /** + * @deprecated To be removed without replacement. + * @forRemoval 4.0.0 + */ + @SuppressWarnings("javadoc") + @Deprecated static boolean isNonQualifiedName(String s) { return isIdentifier(s); } + /** + * @deprecated To be removed without replacement. + * @forRemoval 4.0.0 + */ + @SuppressWarnings("javadoc") + @Deprecated static boolean isIdentifierStart(char c) { return Character.isLetter(c); } + /** + * @deprecated To be removed without replacement. + * @forRemoval 4.0.0 + */ + @SuppressWarnings("javadoc") + @Deprecated static boolean isIdentifierChar(char c) { return (Character.isLetter(c) || Character.isDigit(c) || (c == '_')); } @@ -280,28 +283,12 @@ public abstract class TypeSystemUtils { * @param name * The name to check. * @return <code>true</code> iff <code>name</code> is a possible type name. + * @deprecated Use {@link TypeSystemUtil#isTypeName(String)} instead + * @forRemoval 4.0.0 */ + @Deprecated static boolean isTypeName(String name) { - // Create a string tokenizer that will split the string at the name - // space - // boundaries. We need to see the delimiters to make sure there are no - // gratuitous delimiters at the beginning or the end. - StringTokenizer tok = new StringTokenizer(name, NAMESPACE_SEPARATOR_AS_STRING, true); - // Loop over the tokens and check that every item is an identifier. - while (tok.hasMoreTokens()) { - // Any subsequence must start with an identifier. - if (!isIdentifier(tok.nextToken())) { - return false; - } - // If there is a next token, it must be a separator. - if (tok.hasMoreTokens()) { - // A sequence can not end in a separator. - if (!tok.nextToken().equals(NAMESPACE_SEPARATOR_AS_STRING) || !tok.hasMoreTokens()) { - return false; - } - } - } - return true; + return TypeSystemUtil.isTypeName(name); } static boolean isTypeNameSpaceName(String name) { @@ -357,16 +344,17 @@ public abstract class TypeSystemUtils { if (path.isEmpty()) { return status; } + // Pop the next feature name from the stack and check if it's defined for the current type. - String featName = path.pop(); - FeatureImpl fi = type.getFeatureByBaseName(featName); + var featName = path.pop(); + var fi = type.getFeatureByBaseName(featName); if (fi != null) { // If feature is defined, we can continue directly. return isPathValid(fi.getRangeImpl(), path, status); } + // If feature is not defined for type, check to see if there are any subtypes for which the // path is defined (possible). - return isPathValidInSubtypes(type, featName, path); } @@ -399,9 +387,8 @@ public abstract class TypeSystemUtils { for (TypeImpl subtype : type.getDirectSubtypes()) { FeatureImpl fi = subtype.getFeatureByBaseName(fName); if (fi != null) { - if (PathValid.POSSIBLE == isPathValid(fi.getRangeImpl(), nextPath, PathValid.POSSIBLE)) { // check - // subsequent - // types. + // check subsequent types. + if (PathValid.POSSIBLE == isPathValid(fi.getRangeImpl(), nextPath, PathValid.POSSIBLE)) { return PathValid.POSSIBLE; } else { continue; // try another subtype diff --git a/uimaj-core/src/main/java/org/apache/uima/util/TypeSystemUtil.java b/uimaj-core/src/main/java/org/apache/uima/util/TypeSystemUtil.java index 59b9d8431..5c050440a 100644 --- a/uimaj-core/src/main/java/org/apache/uima/util/TypeSystemUtil.java +++ b/uimaj-core/src/main/java/org/apache/uima/util/TypeSystemUtil.java @@ -24,6 +24,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.StringTokenizer; import org.apache.uima.ResourceSpecifierFactory; import org.apache.uima.UIMAFramework; @@ -42,6 +43,8 @@ import org.apache.uima.spi.TypeSystemDescriptionProvider; public class TypeSystemUtil { + private static final String NAMESPACE_SEPARATOR_AS_STRING = "" + TypeSystem.NAMESPACE_SEPARATOR; + /** * Loads type system descriptions and resolves their imports. For example when you place a * {@link TypeSystemDescriptionProvider} implementation and place the type system descriptions it @@ -206,4 +209,74 @@ public class TypeSystemUtil { return lts.ll_getStringSet(lts.ll_getCodeForType(aType)); } + /** + * @return if the given {@code name} is a valid feature name. Does not check if the feature + * actually exists! + * @param name + * The name to check. + */ + public static boolean isFeatureName(String name) { + + return isIdentifier(name); + } + + /** + * Check if {@code name} is a possible type name. Does not check if this type actually exists! + * + * @param name + * The name to check. + * @return <code>true</code> iff <code>name</code> is a possible type name. + */ + public static boolean isTypeName(String name) { + // Create a string tokenizer that will split the string at the name space + // boundaries. We need to see the delimiters to make sure there are no + // gratuitous delimiters at the beginning or the end. + var tok = new StringTokenizer(name, NAMESPACE_SEPARATOR_AS_STRING, true); + // Loop over the tokens and check that every item is an identifier. + while (tok.hasMoreTokens()) { + // Any subsequence must start with an identifier. + if (!isIdentifier(tok.nextToken())) { + return false; + } + // If there is a next token, it must be a separator. + if (tok.hasMoreTokens()) { + // A sequence can not end in a separator. + if (!tok.nextToken().equals(NAMESPACE_SEPARATOR_AS_STRING) || !tok.hasMoreTokens()) { + return false; + } + } + } + return true; + } + + private static boolean isIdentifier(String s) { + if (s == null) { + return false; + } + final int len = s.length(); + if (len == 0) { + return false; + } + int pos = 0; + // Check that the first character is a letter. + if (!isIdentifierStart(s.charAt(pos))) { + return false; + } + ++pos; + while (pos < len) { + if (!isIdentifierChar(s.charAt(pos))) { + return false; + } + ++pos; + } + return true; + } + + private static boolean isIdentifierStart(char c) { + return Character.isLetter(c); + } + + private static boolean isIdentifierChar(char c) { + return (Character.isLetter(c) || Character.isDigit(c) || (c == '_')); + } }