| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.sdo.helper.extension; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.util.ArrayList; |
| import java.util.StringTokenizer; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.persistence.sdo.SDOConstants; |
| import org.eclipse.persistence.sdo.SDOProperty; |
| import org.eclipse.persistence.sdo.SDOType; |
| import org.eclipse.persistence.internal.helper.ClassConstants; |
| import org.eclipse.persistence.logging.AbstractSessionLog; |
| |
| /** |
| * <p><b>Purpose</b>: Common functions in support of SDO. |
| * <p><b>Responsibilities</b>: |
| * <ul> |
| * <li> JAXB 1.0 Name Mangling algorithm functions are provided to support generation of valid class/method names.. |
| * <li> JSR-222 JAXB 2.0 Java Package Name generation algorithm function follows https://jaxb.dev.java.net/spec-download.html |
| * in section D.5.1 "Mapping from a Namespace URI" |
| * </ul> |
| */ |
| public class SDOUtil { |
| |
| /** Valid hexadecimal digits */ |
| private static final String HEXADECIMAL_DIGITS = "0123456789abcdefABCDEF"; |
| /** Warning string to signify that the input to the package generator may not be a valid URI */ |
| private static final String INVALID_URI_WARNING = "SDOUtil: The URI [{0}] used for java package name generation is invalid - generating [{1}]."; |
| |
| /** NCName start character class content - used to compose {@link #XML_NCNAME_VALIDATION_PATTERN}. */ |
| private static final String XML_NCNAME_START_CHAR_GROUP = |
| "A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\x{10000}-\\x{EFFFF}"; |
| /** NCName character class content - used to compose {@link #XML_NCNAME_VALIDATION_PATTERN}. */ |
| private static final String XML_NCNAME_CHAR_GROUP = |
| "\\-.0-9\\x{B7}\\x{300}-\\x{36F}\\x{203F}-\\x{2040}"; |
| |
| /** |
| * Pattern for validation of XML non-colonial name (NCName). |
| * @see <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">http://www.w3.org/TR/REC-xml-names/#NT-NCName</a> |
| */ |
| private static final Pattern XML_NCNAME_VALIDATION_PATTERN = Pattern.compile( |
| "^[ " + XML_NCNAME_START_CHAR_GROUP + "][" + XML_NCNAME_START_CHAR_GROUP + XML_NCNAME_CHAR_GROUP + "]*$"); |
| |
| private static final String IS = "is"; |
| private static final String GET = "get"; |
| private static final String SET = "set"; |
| |
| /** |
| * INTERNAL: |
| * Search Java reserved name arrays and report (but don't fix) any naming collisions |
| */ |
| private static void preProcessJavaReservedNames(String name) { |
| preProcessReservedNames(name, SDOConstants.javaReservedWordsList, "sdo_type_generation_warning_class_name_violates_java_spec"); |
| } |
| |
| /** |
| * INTERNAL: |
| * Search SDO reserved name arrays and report (but don't fix) any naming collisions |
| */ |
| private static void preProcessSDOReservedNames(String name) { |
| preProcessReservedNames(name, SDOConstants.sdoInterfaceReservedWordsList, "sdo_type_generation_warning_class_name_violates_sdo_spec"); |
| } |
| |
| /** |
| * INTERNAL: |
| * Search reserved name arrays and report (but don't fix) any naming collisions |
| * @param wordArray |
| * @param warningLogKey |
| */ |
| private static void preProcessReservedNames(String name, String[] wordArray, String warningLogKey) { |
| // search the reserved words list and recommend alternatives |
| for(int i=0; i < wordArray.length; i++) { |
| if(wordArray[i].equalsIgnoreCase(name)) { |
| AbstractSessionLog.getLog().log(AbstractSessionLog.WARNING, warningLogKey, // |
| new Object[] { "SDOUtil", name, wordArray[i]}); |
| } |
| } |
| } |
| |
| |
| /** allow _ underscores in class/function names */ |
| private static boolean asWordSeparator = false; |
| |
| /** |
| * INTERNAL: |
| * Get default package name when no targetNamespace URI exists.<br> |
| * This function follows the JSR-222 JAXB 2.0 algorithm from https://jaxb.dev.java.net/spec-download.html<br> |
| * @return default Java package name String |
| */ |
| public static String getDefaultPackageName() { |
| return getPackageNameFromURI(SDOConstants.EMPTY_STRING); |
| } |
| |
| /** |
| * INTERNAL: |
| * Get default package name from a namespace URI.<br> |
| * This function follows the JSR-222 JAXB 2.0 algorithm from https://jaxb.dev.java.net/spec-download.html.<br> |
| * @param uriString - a namespace URL or URN |
| * @return Java package name String |
| */ |
| public static String getPackageNameFromURI(String uriString) { |
| String strToken; |
| String prefix; |
| int position = 0; |
| StringBuffer pkgName = new StringBuffer(); |
| if (null == uriString || uriString.equals(SDOConstants.EMPTY_STRING)) { |
| AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, INVALID_URI_WARNING,// |
| new Object[] { uriString, SDOConstants.JAVA_TYPEGENERATION_DEFAULT_PACKAGE_NAME }, false); |
| return SDOConstants.JAVA_TYPEGENERATION_DEFAULT_PACKAGE_NAME; |
| } |
| |
| /** |
| * Step 1: (Remove the schema and ":" part) |
| * An XML namespace is represented by a URI. Since XML Namespace will be |
| * mapped to a Java package, it is necessary to specify a default mapping from a |
| * URI to a Java package name. The URI format is described in [RFC2396]. |
| * The following steps describe how to map a URI to a Java package name. The |
| * example URI, http://example.org/go/file.xsd, is used to |
| * illustrate each step. |
| * 1. Remove the scheme and ":" part from the beginning of the URI, if present. |
| * Since there is no formal syntax to identify the optional URI scheme, restrict |
| * the schemes to be removed to case insensitive checks for schemes |
| * "http" and "urn". |
| * //example.org/go/file.xsd |
| */ |
| // Remove only urn: and http: schemes - retain ftp, file, gopher, mail, news, telnet |
| URI uri; |
| String originalUriString = uriString; |
| String schemePrefix; |
| // Save error state so that we can emit a warning after the URI has been processed |
| boolean invalidOriginalFormat = false; |
| // Save whether we are a supported urn or http scheme |
| boolean invalidScheme = false; |
| try { |
| // Creating a URI object and catching a syntax exception may be a performance hit |
| uri = new URI(uriString); |
| schemePrefix = uri.getScheme(); |
| // Remove http or urn schemes for valid URI's |
| if(null != schemePrefix){ |
| if((schemePrefix.equalsIgnoreCase("http") || schemePrefix.equalsIgnoreCase("urn"))) { |
| uriString = uri.getSchemeSpecificPart(); |
| }else{ |
| invalidScheme = true; |
| } |
| } |
| } catch (NullPointerException npe) { |
| AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, INVALID_URI_WARNING,// |
| new Object[] { "null", SDOConstants.JAVA_TYPEGENERATION_DEFAULT_PACKAGE_NAME }, false); |
| return SDOConstants.JAVA_TYPEGENERATION_DEFAULT_PACKAGE_NAME; |
| } catch (URISyntaxException use) { |
| // Warn that the URI is invalid, but process the string into a valid package anyway |
| invalidOriginalFormat = true; |
| // Remove http or urn schemes for invalid URI's |
| if (uriString.length() > 4) { |
| prefix = uriString.substring(0, 4); |
| if (prefix.equalsIgnoreCase("urn:")) { |
| uriString = uriString.substring(4); |
| } else { |
| prefix = uriString.substring(0, 5); |
| if (prefix.equalsIgnoreCase("http:")) { |
| uriString = uriString.substring(5); |
| } |
| } |
| } |
| } finally { |
| /** |
| * Step 2: remove trailing file type, one of .?? or .??? or .html. |
| * //example.org/go/file |
| * Note: The trailing host fragment will be removed for non http|urn schemes such as file:. |
| */ |
| int potentialPathSepIndex = uriString.lastIndexOf('/'); // Don't handle ? param separator on purpose |
| int potentialHostSepIndex = uriString.indexOf('/'); |
| int potentialFileExtIndex = uriString.lastIndexOf('.'); |
| /** |
| * When to remove the last .ext or trailing host fragment. |
| * Valid scheme | has file ext = remove/keep last {.[^.]+} fragment |
| * 0 | 0 Remove host prefix ie: file://site.com -> file.site |
| * 0 | 1 Remove file ext ie: file://site.com/file.xsd -> file.com.site |
| * 1 | 0 Don't remove host prefix ie: urn://site.com -> com.site |
| * 1 | 1 Remove file ext ie: urn://site.com/file.xsd -> com.site |
| */ |
| // Don't Remove trailing host fragment for http|urn schemes |
| if((invalidScheme && potentialFileExtIndex != -1) || // |
| ((potentialFileExtIndex != -1 && potentialPathSepIndex != -1 && // |
| potentialHostSepIndex != -1 && (potentialPathSepIndex - potentialHostSepIndex) > 1))) { // -1's are handled |
| String extension = uriString.substring(potentialFileExtIndex); |
| if (extension.length() == 3 || extension.length() == 4 || extension.equalsIgnoreCase(".html")) { |
| uriString = uriString.substring(0, potentialFileExtIndex); |
| } |
| } |
| |
| /** |
| * Step 3: (split string into word list) 3. Parse the remaining |
| * String into a list of strings using / and : as separators |
| * Treat consecutive separators as a single separator. |
| * {"example.org", "go", "file" } |
| */ |
| StringTokenizer aTokenizer = new StringTokenizer(uriString, "/:"); |
| int length = aTokenizer.countTokens(); |
| if (length == 0) { |
| return SDOConstants.JAVA_TYPEGENERATION_DEFAULT_PACKAGE_NAME; |
| } |
| |
| /** |
| * Step 4: (unescape each escape sequence octet) 4. For each string |
| * in the list produced by previous step, unescape each escape |
| * sequence octet. {"example.org", "go", "file" } Generating a |
| * Java package name 4/19/06 JAXB 2.0 - Final Release 341 |
| */ |
| ArrayList<String> strings = new ArrayList<String>(length); |
| while (aTokenizer.hasMoreTokens()) { |
| strToken = aTokenizer.nextToken(); |
| strings.add(decodeUriHexadecimalEscapeSequence(strToken)); |
| } |
| |
| /** |
| * Step 5: replace [-] with [.] if the scheme is a URN 5. If the |
| * scheme is a urn, replace all dashes, -, occurring in the |
| * first component with [.].2 |
| */ |
| |
| /** |
| * Step 6: Apply algorithm described in Section 7.7 Unique Package |
| * Names in [JLS] to derive a unique package name from the |
| * potential internet domain name contained within the first |
| * component. The internet domain name is reversed, component by |
| * component. Note that a leading www. is not considered part of |
| * an internet domain name and must be dropped. If the first |
| * component does not contain either one of the top-level domain |
| * names, for example, com, gov, net, org, edu, or one of the |
| * English two-letter codes identifying countries as specified in |
| * ISO Standard 3166, 1981, this step must be skipped. {org, |
| * example, go, file} |
| */ |
| strToken = strings.remove(0).toLowerCase(); |
| // Reuse the Tokenizer - tokenize on package separator |
| aTokenizer = new StringTokenizer(strToken, "."); |
| // Check for URI's that are composed only of metacharacter package separators |
| if(aTokenizer.countTokens() < 1) { |
| AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST, INVALID_URI_WARNING,// |
| new Object[] { uriString, SDOConstants.JAVA_TYPEGENERATION_DEFAULT_PACKAGE_NAME }, false); |
| return SDOConstants.JAVA_TYPEGENERATION_DEFAULT_PACKAGE_NAME; |
| } else { |
| while (aTokenizer.hasMoreTokens()) { |
| strToken = aTokenizer.nextToken(); |
| if (!strToken.equals("www")) { |
| strings.add(0, strToken); |
| } |
| } |
| } |
| |
| /** |
| * Step 7: (convert each string to be all lower case) 7. For each |
| * string in the list, convert each string to be all lower case. |
| * {org, example, go, file } |
| */ |
| position = 0; |
| for (String aString : strings) { |
| strings.set(position++, aString.toLowerCase()); |
| } |
| |
| /** |
| * Step 8: (convert each string to a valid identifier) 8. For each |
| * string remaining, the following conventions are adopted from |
| * [JLS] Section 7.7, Unique Package Names. Follow step 8a-c |
| * below. |
| */ |
| position = 0; |
| for (String aString : strings) { |
| StringBuffer buffer = new StringBuffer(); |
| |
| /** |
| * Step 8a: If the string component contains a hyphen, or any other |
| * special character not allowed in an identifier, convert it |
| * into an underscore. |
| */ |
| for (int j = 0; j < aString.length(); j++) { |
| char charToken = aString.charAt(j); |
| if (Character.isJavaIdentifierPart(charToken)) { |
| buffer.append(charToken); |
| } else { |
| buffer.append('_'); |
| } |
| } |
| |
| /** |
| * Step 8b: |
| * From the Java Language Specification section 7.7 b. If any of |
| * the resulting package name components are keywords then |
| * append underscore to them. |
| * We are not performing this step here - and are allowing all java reserved keywords to pass |
| * See the enum com.sun.tools.javac.parser.Token for a list of keywords |
| */ |
| |
| /** |
| * Step 8c: If any of the resulting package name components start with |
| * a digit, or any other character that is not allowed as an |
| * initial character of an identifier, have an underscore |
| * prefixed to the component. {org, example, go, file } |
| */ |
| if (!Character.isJavaIdentifierStart(buffer.charAt(0))) { |
| buffer.insert(0, '_'); |
| } |
| if (position++ != 0) { |
| buffer.insert(0, '.'); |
| } |
| |
| pkgName.append(buffer.toString()); |
| } |
| if(invalidOriginalFormat) { |
| AbstractSessionLog.getLog().log(AbstractSessionLog.FINEST,// |
| INVALID_URI_WARNING, new Object[] { originalUriString, pkgName }, false); |
| } |
| } |
| return pkgName.toString(); |
| } |
| |
| /** |
| * INTERNAL: |
| * Decode Hexadecimal "%hh" escape sequences in a URI. |
| * All escape codes must be valid 2 digit sequences. |
| * |
| * @param uri - URI component |
| * @return URI component with escape sequence decoded into a |
| */ |
| private static String decodeUriHexadecimalEscapeSequence(String uri) { |
| // This function is used by the Java Package Name generation algorithm that implements JAXB 2.0 D.5.1 |
| StringBuffer sb = new StringBuffer(uri.length()); |
| for (int index = 0; index < uri.length(); index++) { |
| char c = uri.charAt(index); |
| // Escape sequence found - get the hex value and convert |
| if (c == '%') { |
| if (((index + 2) < uri.length()) && // |
| HEXADECIMAL_DIGITS.indexOf(uri.charAt(index + 1)) >= 0 &&// |
| HEXADECIMAL_DIGITS.indexOf(uri.charAt(index + 2)) >= 0) { |
| // Look ahead 2 digits |
| String g = uri.substring(index + 1, index + 3); |
| // Convert base 16 to base 10 to char and append |
| sb.append((char)Integer.parseInt(g, 16)); |
| /** |
| * Increase the index by 2 - so we skip the 2 digit hex code after the % |
| * See JAXB 2.0 spec p.348 section D.5.1.4 |
| * "For each string in the list produced by step 3. Unescape each escape sequence octet. |
| * IE: North%20America should be "North America" and later in step 8 |
| * "north_america" not "north_20america" |
| */ |
| index+=2; |
| } else { |
| sb.append(c); |
| } |
| } else { |
| sb.append(c); |
| } |
| } |
| return (sb.toString()); |
| } |
| |
| |
| /** |
| * INTERNAL: |
| * Return a valid Java class name or method name for a given string |
| * @param s |
| * @param isClass (flag whether called from a method context) |
| * @return |
| */ |
| public static String className(String s, boolean isClass) { |
| return className(s, true, isClass, true); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a valid Java class name or method name for a given string |
| * @param s |
| * @param isClass (flag whether called from a method context) |
| * @param flag |
| * @return |
| */ |
| public static String className(String s, boolean flag, boolean isClass, boolean logOn) { |
| // 1) warn if the class conflicts with any Java reserved words |
| preProcessJavaReservedNames(s); |
| // 2) warn if the class conflicts with any SDO reserved words |
| preProcessSDOReservedNames(s); |
| |
| String[] as = getWordList(s); |
| StringBuffer stringbuffer = new StringBuffer(); |
| StringBuffer stringbuffer1 = new StringBuffer(); |
| if (as.length == 0) { |
| return stringbuffer.toString(); |
| } |
| |
| for (int i = 0; i < as.length; i++) { |
| char[] ac = as[i].toCharArray(); |
| if (Character.isLowerCase(ac[0])) { |
| ac[0] = Character.toUpperCase(ac[0]); |
| } |
| for (int j = 0; j < ac.length; j++) { |
| if ((ac[j] >= ' ') && (ac[j] < '\177')) { |
| if ((ac[j] != '_') || !asWordSeparator) { |
| stringbuffer.append(ac[j]); |
| } |
| continue; |
| } |
| if (flag) { |
| stringbuffer.append(escapeUnicode(stringbuffer1, ac[j])); |
| } else { |
| stringbuffer.append(ac[j]); |
| } |
| } |
| } |
| |
| String normalizedName = stringbuffer.toString(); |
| // report a warning whether we were required to normalize the name (beyond initial capitalization) |
| if(!s.equals(normalizedName) && logOn) { |
| // log changes |
| int logLevel; |
| // log capitalization-only changes at a lower level |
| if(!s.equalsIgnoreCase(normalizedName)) { |
| logLevel = AbstractSessionLog.INFO; |
| } else { |
| logLevel = AbstractSessionLog.FINER; |
| } |
| |
| // report differently depending on whether the input was a class or function name |
| if(isClass) { |
| AbstractSessionLog.getLog().log(logLevel, // |
| "sdo_type_generation_modified_class_naming_format_to", |
| new Object[] { "SDOUtil", s, normalizedName}); |
| } else { |
| AbstractSessionLog.getLog().log(logLevel, // |
| "sdo_type_generation_modified_function_naming_format_to", |
| new Object[] { "SDOUtil", s, normalizedName}); |
| } |
| } |
| |
| return normalizedName; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a valid Java method name for a given string |
| * @param s |
| * @return |
| */ |
| public static String methodName(String s) { |
| return methodName(s, true); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a valid Java method name for a given string |
| * @param s |
| * @param flag |
| * @return |
| */ |
| public static String methodName(String s, boolean flag) { |
| return className(s, flag, false, true); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a valid Java set method name for a given string |
| * @param s |
| * @return |
| */ |
| public static String setMethodName(String s) { |
| StringBuffer stringbuffer = new StringBuffer(); |
| stringbuffer.append(SET).append(methodName(s)); |
| return stringbuffer.toString(); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a valid Java get method name for a given string. This method will check |
| * the returnType to see if it is a boolean/Boolean: if so, 'is' will be used in |
| * the method name instead of 'get'. |
| * |
| * @param s |
| * @param returnType |
| * @return |
| */ |
| public static String getMethodName(String s, String returnType) { |
| StringBuffer stringBuffer = new StringBuffer(); |
| if (returnType.equals(ClassConstants.PBOOLEAN.getName()) || returnType.equals(ClassConstants.BOOLEAN.getName())) { |
| stringBuffer.append(IS); |
| } else { |
| stringBuffer.append(GET); |
| } |
| stringBuffer.append(SDOUtil.className(s, true, false, false)); |
| return stringBuffer.toString(); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a valid Java get method name for a given string. This method will NOT check |
| * the returnType to see if it is a boolean/Boolean and all method names will start with |
| * "GET" |
| * |
| * @param s |
| * @param returnType |
| * @return |
| */ |
| public static String getBooleanGetMethodName(String s, String returnType){ |
| StringBuffer stringBuffer = new StringBuffer(); |
| stringBuffer.append(SDOUtil.GET); |
| stringBuffer.append(SDOUtil.className(s, true, false, false)); |
| return stringBuffer.toString(); |
| } |
| |
| /** |
| * INTERNAL: |
| * @param s |
| * @return |
| */ |
| public static String constantName(String s) { |
| StringBuffer stringbuffer = new StringBuffer(); |
| String[] as = getWordList(s); |
| if (as.length > 0) { |
| stringbuffer.append(as[0].toUpperCase()); |
| for (int i = 1; i < as.length; i++) { |
| stringbuffer.append('_'); |
| stringbuffer.append(as[i].toUpperCase()); |
| } |
| } |
| return stringbuffer.toString(); |
| } |
| |
| /** |
| * |
| * @param s |
| * @return |
| */ |
| private static String[] getWordList(String s) { |
| java.util.List arraylist = new ArrayList(); |
| int i = s.length(); |
| int j = 0; |
| do { |
| if (j >= i) { |
| break; |
| } |
| for (; (j < i) && isPunct(s.charAt(j)); j++) { |
| } |
| if (j >= i) { |
| break; |
| } |
| int k = nextBreak(s, j); |
| String s1 = (k != -1) ? s.substring(j, k) : s.substring(j); |
| arraylist.add(escape(s1)); |
| if (k == -1) { |
| break; |
| } |
| j = k; |
| } while (true); |
| return (String[])arraylist.toArray(new String[0]); |
| } |
| |
| private static boolean isPunct(char c) { |
| if ((c == '-') || (c == '.') || (c == ':') || (c == '\267') || (c == '\u0387') || (c == '\u06DD') || (c == '\u06DE')) { |
| return true; |
| } |
| return (c == '_') && asWordSeparator; |
| } |
| |
| private static boolean isUncased(char c) { |
| return Character.isLetter(c) && !Character.isUpperCase(c) && !Character.isLowerCase(c); |
| } |
| |
| private static int nextBreak(String s, int i) { |
| int j = s.length(); |
| for (int k = i; k < j; k++) { |
| char c = s.charAt(k); |
| if (((c == '_') && !asWordSeparator) || (k >= (j - 1))) { |
| continue; |
| } |
| char c1 = s.charAt(k + 1); |
| if ((c1 == '_') && !asWordSeparator) { |
| continue; |
| } |
| if (isPunct(c1)) { |
| return k + 1; |
| } |
| if (Character.isDigit(c) && !Character.isDigit(c1)) { |
| return k + 1; |
| } |
| if (!Character.isDigit(c) && Character.isDigit(c1)) { |
| return k + 1; |
| } |
| if (Character.isLowerCase(c) && !Character.isLowerCase(c1)) { |
| return k + 1; |
| } |
| if (k < (j - 2)) { |
| char c2 = s.charAt(k + 2); |
| if ((c2 == '_') && !asWordSeparator) { |
| continue; |
| } |
| if (Character.isUpperCase(c) && Character.isUpperCase(c1) && Character.isLowerCase(c2)) { |
| return k + 1; |
| } |
| } |
| if (Character.isLetter(c) && !Character.isLetter(c1)) { |
| return k + 1; |
| } |
| if (!Character.isLetter(c) && Character.isLetter(c1)) { |
| return k + 1; |
| } |
| if (isUncased(c) && !isUncased(c1)) { |
| return k + 1; |
| } |
| if (!isUncased(c) && isUncased(c1)) { |
| return k + 1; |
| } |
| } |
| return -1; |
| } |
| |
| private static String escape(String s) { |
| int i = s.length(); |
| for (int j = 0; j < i; j++) { |
| if (!Character.isJavaIdentifierPart(s.charAt(j))) { |
| StringBuffer stringbuffer = new StringBuffer(s.substring(0, j)); |
| escape(stringbuffer, s, j); |
| return stringbuffer.toString(); |
| } |
| } |
| return s; |
| } |
| |
| private static void escape(StringBuffer stringbuffer, String s, int i) { |
| int j = s.length(); |
| for (int k = i; k < j; k++) { |
| char c = s.charAt(k); |
| if (Character.isJavaIdentifierPart(c)) { |
| stringbuffer.append(c); |
| continue; |
| } |
| stringbuffer.append("_"); |
| if (c <= '\017') { |
| stringbuffer.append("000"); |
| } else if (c <= '\377') { |
| stringbuffer.append("00"); |
| } else if (c <= '\u0FFF') { |
| stringbuffer.append("0"); |
| } |
| stringbuffer.append(Integer.toString(c, 16)); |
| } |
| } |
| |
| private static String escapeUnicode(StringBuffer stringbuffer, char c) { |
| String s = Integer.toString(c, 16); |
| int i = s.length(); |
| stringbuffer.setLength(6); |
| stringbuffer.setCharAt(0, '\\'); |
| stringbuffer.setCharAt(1, 'u'); |
| int j = 2; |
| for (int k = i; k < 4;) { |
| stringbuffer.setCharAt(j, '0'); |
| k++; |
| j++; |
| } |
| |
| stringbuffer.replace(j, 6, s); |
| return stringbuffer.toString(); |
| } |
| |
| public static String getJavaTypeForProperty(SDOProperty property) { |
| if (property.isMany() || property.getType().isXsdList()) { |
| return "java.util.List"; |
| } else { |
| SDOType propertyType = property.getType(); |
| if(propertyType.isDataType()) { |
| Class<?> instanceClass = propertyType.getInstanceClass(); |
| if (ClassConstants.ABYTE.equals(instanceClass)) { |
| return "Byte[]"; |
| } else if (ClassConstants.APBYTE.equals(instanceClass)) { |
| return "byte[]"; |
| } |
| } |
| return propertyType.getInstanceClassName(); |
| } |
| } |
| |
| public static String getBuiltInType(String typeName) { |
| if ((typeName.equals(ClassConstants.PBOOLEAN.getName())) || (typeName.equals(ClassConstants.BOOLEAN.getName()))) { |
| return "Boolean"; |
| } else if ((typeName.equals(ClassConstants.PBYTE.getName())) || (typeName.equals(ClassConstants.BYTE.getName()))) { |
| return "Byte"; |
| } else if (typeName.equals("byte[]") || typeName.equals("Byte[]") || (typeName.equals(ClassConstants.APBYTE.getName())) || (typeName.equals(ClassConstants.ABYTE.getName()))) { |
| return "Bytes"; |
| } else if ((typeName.equals(ClassConstants.PCHAR.getName())) || (typeName.equals(ClassConstants.CHAR.getName()))) { |
| return "Char"; |
| } else if ((typeName.equals(ClassConstants.PDOUBLE.getName())) || (typeName.equals(ClassConstants.DOUBLE.getName()))) { |
| return "Double"; |
| } else if ((typeName.equals(ClassConstants.PFLOAT.getName())) || (typeName.equals(ClassConstants.FLOAT.getName()))) { |
| return "Float"; |
| } else if ((typeName.equals(ClassConstants.PLONG.getName())) || (typeName.equals(ClassConstants.LONG.getName()))) { |
| return "Long"; |
| } else if ((typeName.equals(ClassConstants.PSHORT.getName())) || (typeName.equals(ClassConstants.SHORT.getName()))) { |
| return "Short"; |
| } else if ((typeName.equals(ClassConstants.PINT.getName())) || (typeName.equals(ClassConstants.INTEGER.getName()))) { |
| return "Int"; |
| } else if (typeName.equals(ClassConstants.STRING.getName())) { |
| return "String"; |
| } else if (typeName.equals(ClassConstants.BIGINTEGER.getName())) { |
| return "BigInteger"; |
| } else if (typeName.equals(ClassConstants.BIGDECIMAL.getName())) { |
| return "BigDecimal"; |
| } else if (typeName.equals(ClassConstants.UTILDATE.getName())) { |
| return "Date"; |
| } else if (typeName.equals("java.util.List")) { |
| return "List"; |
| } |
| return null; |
| } |
| |
| /** |
| * INTERNAL: |
| * Validates whether given string is a valid XML non-colonial name (NCName). |
| * @param name string |
| * @return {@code true} given string is a valid NCName |
| * @see <a href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">http://www.w3.org/TR/REC-xml-names/#NT-NCName</a> |
| */ |
| public static boolean isValidXmlNCName(String name) { |
| return XML_NCNAME_VALIDATION_PATTERN.matcher(name).matches(); |
| } |
| } |