X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=code-generator%2Fbinding-generator-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fbinding%2Fgenerator%2Futil%2FBindingGeneratorUtil.java;h=6e961701e907549ee6071a9535fc03191f4329d1;hb=e11cb6194bd7adbdf0c2449ee24d212a1e8d7b1c;hp=77259cabce5ad3d206e8599ba042cce0b34886d5;hpb=3bc4c6f9dbc85d6e6076f67f27bc2e945dc500ba;p=mdsal.git diff --git a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java index 77259cabce..6e961701e9 100644 --- a/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java +++ b/code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java @@ -1,366 +1,445 @@ -package org.opendaylight.yangtools.binding.generator.util; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Calendar; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; -import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.model.api.TypeDefinition; - -/** - * Contains the methods for converting strings to valid JAVA language strings - * (package names, class names, attribute names). - * - * - */ -public final class BindingGeneratorUtil { - - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyMMdd"); - - /** - * Array of strings values which represents JAVA reserved words. - */ - private static final String[] SET_VALUES = new String[] { "abstract", "assert", "boolean", "break", "byte", "case", - "catch", "char", "class", "const", "continue", "default", "double", "do", "else", "enum", "extends", - "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", - "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", - "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", - "true", "try", "void", "volatile", "while" }; - - /** - * Impossible to instantiate this class. All of the methods or attributes - * are static. - */ - private BindingGeneratorUtil() { - } - - /** - * Hash set of words which are reserved in JAVA language. - */ - private static final Set JAVA_RESERVED_WORDS = new HashSet(Arrays.asList(SET_VALUES)); - - /** - * Converts string packageName to valid JAVA package name. - * - * If some words of package name are digits of JAVA reserved words they are - * prefixed with underscore character. - * - * @param packageName - * string which contains words separated by point. - * @return package name which contains words separated by point. - */ - private static String validateJavaPackage(final String packageName) { - if (packageName != null) { - final String[] packNameParts = packageName.split("\\."); - if (packNameParts != null) { - final StringBuilder builder = new StringBuilder(); - for (int i = 0; i < packNameParts.length; ++i) { - final String packNamePart = packNameParts[i]; - if (Character.isDigit(packNamePart.charAt(0))) { - packNameParts[i] = "_" + packNamePart; - } else if (JAVA_RESERVED_WORDS.contains(packNamePart)) { - packNameParts[i] = "_" + packNamePart; - } - if (i > 0) { - builder.append("."); - } - builder.append(packNameParts[i]); - } - return builder.toString(); - } - } - return packageName; - } - - /** - * Converts parameterName to valid JAVA parameter name. - * - * If the parameterName is one of the JAVA reserved words then - * it is prefixed with underscore character. - * - * @param parameterName - * string with the parameter name - * @return string with the admissible parameter name - */ - public static String validateParameterName(final String parameterName) { - if (parameterName != null) { - if (JAVA_RESERVED_WORDS.contains(parameterName)) { - return "_" + parameterName; - } - } - return parameterName; - } - - /** - * Creates generated TO builder from packageName and - * transObjectName. - * - * @param packageName - * string with name of package to which the returned object - * belongs - * @param transObjectName - * string with name which the returned object has - * @return generated TO builder or null value if - * packageName or transObjectName equal - * null - */ - public static GeneratedTOBuilder schemaNodeToTransferObjectBuilder(final String packageName, - final String transObjectName) { - if (packageName != null && transObjectName != null) { - - final String genTOName = BindingGeneratorUtil.parseToClassName(transObjectName); - final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(packageName, genTOName); - - return newType; - - } - return null; - } - - /** - * Converts module name to valid JAVA package name. - * - * The package name consists of: - * - * - * @param module - * module which contains data about namespace and revision date - * @return string with the valid JAVA package name - * @throws IllegalArgumentException - * if the revision date of the module equals - * null - */ - public static String moduleNamespaceToPackageName(final Module module) { - final StringBuilder packageNameBuilder = new StringBuilder(); - - if (module.getRevision() == null) { - throw new IllegalArgumentException("Module " + module.getName() + " does not specify revision date!"); - } - packageNameBuilder.append("org.opendaylight.yang.gen.v"); - packageNameBuilder.append(module.getYangVersion()); - packageNameBuilder.append("."); - - String namespace = module.getNamespace().toString(); - namespace = namespace.replace("://", "."); - namespace = namespace.replace("/", "."); - namespace = namespace.replace(":", "."); - namespace = namespace.replace("-", "."); - namespace = namespace.replace("@", "."); - namespace = namespace.replace("$", "."); - namespace = namespace.replace("#", "."); - namespace = namespace.replace("'", "."); - namespace = namespace.replace("*", "."); - namespace = namespace.replace("+", "."); - namespace = namespace.replace(",", "."); - namespace = namespace.replace(";", "."); - namespace = namespace.replace("=", "."); - - packageNameBuilder.append(namespace); - packageNameBuilder.append(".rev"); - packageNameBuilder.append(DATE_FORMAT.format(module.getRevision())); - - return validateJavaPackage(packageNameBuilder.toString()); - } - - /** - * Creates package name from specified basePackageName (package - * name for module) and schemaPath. - * - * Resulting package name is concatenation of basePackageName - * and all local names of YANG nodes which are parents of some node for - * which schemaPath is specified. - * - * @param basePackageName - * string with package name of the module - * @param schemaPath - * list of names of YANG nodes which are parents of some node + - * name of this node - * @return string with valid JAVA package name - */ - public static String packageNameForGeneratedType(final String basePackageName, final SchemaPath schemaPath) { - if (basePackageName == null) { - throw new IllegalArgumentException("Base Package Name cannot be NULL!"); - } - if (schemaPath == null) { - throw new IllegalArgumentException("Schema Path cannot be NULL!"); - } - - final StringBuilder builder = new StringBuilder(); - builder.append(basePackageName); - final List pathToNode = schemaPath.getPath(); - final int traversalSteps = (pathToNode.size() - 1); - for (int i = 0; i < traversalSteps; ++i) { - builder.append("."); - String nodeLocalName = pathToNode.get(i).getLocalName(); - - nodeLocalName = nodeLocalName.replace(":", "."); - nodeLocalName = nodeLocalName.replace("-", "."); - builder.append(nodeLocalName); - } - return validateJavaPackage(builder.toString()); - } - - /** - * Generates the package name for type definition from - * typeDefinition and basePackageName. - * - * @param basePackageName - * string with the package name of the module - * @param typeDefinition - * type definition for which the package name will be generated * - * @return string with valid JAVA package name - * @throws IllegalArgumentException - *
    - *
  • if basePackageName equals null
  • - *
  • if typeDefinition equals null
  • - *
- */ - public static String packageNameForTypeDefinition(final String basePackageName, - final TypeDefinition typeDefinition) { - if (basePackageName == null) { - throw new IllegalArgumentException("Base Package Name cannot be NULL!"); - } - if (typeDefinition == null) { - throw new IllegalArgumentException("Type Definition reference cannot be NULL!"); - } - - final StringBuilder builder = new StringBuilder(); - builder.append(basePackageName); - return validateJavaPackage(builder.toString()); - } - - /** - * Converts token to string which is in accordance with best - * practices for JAVA class names. - * - * @param token - * string which contains characters which should be converted to - * JAVA class name - * @return string which is in accordance with best practices for JAVA class - * name. - */ - public static String parseToClassName(String token) { - token = token.replace(".", ""); - String correctStr = parseToCamelCase(token); - - // make first char upper-case - char first = Character.toUpperCase(correctStr.charAt(0)); - if(first >= '0' && first <= '9') { - - correctStr = "_" + correctStr; - } else { - correctStr = first + correctStr.substring(1); - } - return correctStr; - } - - /** - * Converts token to string which is in accordance with best - * practices for JAVA parameter names. - * - * @param token - * string which contains characters which should be converted to - * JAVA parameter name - * @return string which is in accordance with best practices for JAVA - * parameter name. - */ - public static String parseToValidParamName(final String token) { - final String validToken = token.replace(".", ""); - String correctStr = parseToCamelCase(validToken); - - // make first char lower-case - char first = Character.toLowerCase(correctStr.charAt(0)); - correctStr = first + correctStr.substring(1); - return validateParameterName(correctStr); - } - - /** - * Converts token to capital letters and removes invalid - * characters. - * - * @param token - * string with characters which should be conversed to capital - * @return string with capital letters - */ - public static String convertToCapitalLetters(final String token) { - String convertedStr = token.replace(" ", "_"); - convertedStr = convertedStr.replace(".", "_"); - convertedStr = convertedStr.toUpperCase(); - return convertedStr; - } - - /** - * - * Converts string token to the cammel case format. - * - * @param token - * string which should be converted to the cammel case format - * @return string in the cammel case format - * @throws NullPointerException - * - if token equals null - * @throws IllegalArgumentException - * - if token without white spaces is empty - */ - private static String parseToCamelCase(String token) { - if (token == null) { - throw new NullPointerException("Name can not be null"); - } - - String correctStr = token.trim(); - if (correctStr.isEmpty()) { - throw new IllegalArgumentException("Name can not be emty"); - } - - correctStr = replaceWithCamelCase(correctStr, ' '); - correctStr = replaceWithCamelCase(correctStr, '-'); - correctStr = replaceWithCamelCase(correctStr, '_'); - return correctStr; - } - - /** - * Replaces all the occurances of the removalChar in the - * text with empty string and converts following character to - * upper case. - * - * @param text - * string with source text which should be converted - * @param removalChar - * character which is sought in the text - * @return string which doesn't contain removalChar and has - * following characters converted to upper case - * @throws IllegalArgumentException - * if the length of the returning string has length 0 - */ - private static String replaceWithCamelCase(String text, char removalChar) { - StringBuilder sb = new StringBuilder(text); - String toBeRemoved = String.valueOf(removalChar); - - int toBeRemovedPos = sb.indexOf(toBeRemoved); - while (toBeRemovedPos != -1) { - sb.replace(toBeRemovedPos, toBeRemovedPos + 1, ""); - // check if 'toBeRemoved' character is not the only character in - // 'text' - if (sb.length() == 0) { - throw new IllegalArgumentException("The resulting string can not be empty"); - } - String replacement = String.valueOf(sb.charAt(toBeRemovedPos)).toUpperCase(); - sb.setCharAt(toBeRemovedPos, replacement.charAt(0)); - toBeRemovedPos = sb.indexOf(toBeRemoved); - } - return sb.toString(); - } -} +package org.opendaylight.yangtools.binding.generator.util; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl; +import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier; +import org.opendaylight.yangtools.sal.binding.model.api.Restrictions; +import org.opendaylight.yangtools.sal.binding.model.api.Type; +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder; +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder; +import org.opendaylight.yangtools.sal.binding.model.api.type.builder.TypeMemberBuilder; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition; +import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint; +import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint; +import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; +import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; + +/** + * Contains the methods for converting strings to valid JAVA language strings + * (package names, class names, attribute names). + * + * + */ +public final class BindingGeneratorUtil { + + private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyMMdd"); + + /** + * Array of strings values which represents JAVA reserved words. + */ + private static final String[] SET_VALUES = new String[] { "abstract", "assert", "boolean", "break", "byte", "case", + "catch", "char", "class", "const", "continue", "default", "double", "do", "else", "enum", "extends", + "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", + "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", + "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", + "true", "try", "void", "volatile", "while" }; + + /** + * Impossible to instantiate this class. All of the methods or attributes + * are static. + */ + private BindingGeneratorUtil() { + } + + /** + * Hash set of words which are reserved in JAVA language. + */ + private static final Set JAVA_RESERVED_WORDS = new HashSet(Arrays.asList(SET_VALUES)); + + /** + * Converts string packageName to valid JAVA package name. + * + * If some words of package name are digits of JAVA reserved words they are + * prefixed with underscore character. + * + * @param packageName + * string which contains words separated by point. + * @return package name which contains words separated by point. + */ + private static String validateJavaPackage(final String packageName) { + if (packageName != null) { + final String[] packNameParts = packageName.toLowerCase().split("\\."); + if (packNameParts != null) { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < packNameParts.length; ++i) { + final String packNamePart = packNameParts[i]; + if (Character.isDigit(packNamePart.charAt(0))) { + packNameParts[i] = "_" + packNamePart; + } else if (JAVA_RESERVED_WORDS.contains(packNamePart)) { + packNameParts[i] = "_" + packNamePart; + } + if (i > 0) { + builder.append("."); + } + builder.append(packNameParts[i]); + } + return builder.toString(); + } + } + return packageName; + } + + /** + * Converts parameterName to valid JAVA parameter name. + * + * If the parameterName is one of the JAVA reserved words then + * it is prefixed with underscore character. + * + * @param parameterName + * string with the parameter name + * @return string with the admissible parameter name + */ + public static String resolveJavaReservedWordEquivalency(final String parameterName) { + if (parameterName != null && JAVA_RESERVED_WORDS.contains(parameterName)) { + return "_" + parameterName; + } + return parameterName; + } + + /** + * Converts module name to valid JAVA package name. + * + * The package name consists of: + *
    + *
  • prefix - org.opendaylight.yang.gen.v
  • + *
  • module YANG version - org.opendaylight.yang.gen.v
  • + *
  • module namespace - invalid characters are replaced with dots
  • + *
  • revision prefix - .rev
  • + *
  • revision - YYYYMMDD (MM and DD aren't spread to the whole length)
  • + *
+ * + * @param module + * module which contains data about namespace and revision date + * @return string with the valid JAVA package name + * @throws IllegalArgumentException + * if the revision date of the module equals + * null + */ + public static String moduleNamespaceToPackageName(final Module module) { + final StringBuilder packageNameBuilder = new StringBuilder(); + + if (module.getRevision() == null) { + throw new IllegalArgumentException("Module " + module.getName() + " does not specify revision date!"); + } + packageNameBuilder.append("org.opendaylight.yang.gen.v"); + packageNameBuilder.append(module.getYangVersion()); + packageNameBuilder.append("."); + + String namespace = module.getNamespace().toString(); + namespace = namespace.replace("://", "."); + namespace = namespace.replace("/", "."); + namespace = namespace.replace(":", "."); + namespace = namespace.replace("-", "."); + namespace = namespace.replace("@", "."); + namespace = namespace.replace("$", "."); + namespace = namespace.replace("#", "."); + namespace = namespace.replace("'", "."); + namespace = namespace.replace("*", "."); + namespace = namespace.replace("+", "."); + namespace = namespace.replace(",", "."); + namespace = namespace.replace(";", "."); + namespace = namespace.replace("=", "."); + + packageNameBuilder.append(namespace); + packageNameBuilder.append(".rev"); + packageNameBuilder.append(DATE_FORMAT.format(module.getRevision())); + + return validateJavaPackage(packageNameBuilder.toString()); + } + + /** + * Creates package name from specified basePackageName (package + * name for module) and schemaPath. + * + * Resulting package name is concatenation of basePackageName + * and all local names of YANG nodes which are parents of some node for + * which schemaPath is specified. + * + * @param basePackageName + * string with package name of the module + * @param schemaPath + * list of names of YANG nodes which are parents of some node + + * name of this node + * @return string with valid JAVA package name + */ + public static String packageNameForGeneratedType(final String basePackageName, final SchemaPath schemaPath) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (schemaPath == null) { + throw new IllegalArgumentException("Schema Path cannot be NULL!"); + } + + final StringBuilder builder = new StringBuilder(); + builder.append(basePackageName); + final List pathToNode = schemaPath.getPath(); + final int traversalSteps = (pathToNode.size() - 1); + for (int i = 0; i < traversalSteps; ++i) { + builder.append("."); + String nodeLocalName = pathToNode.get(i).getLocalName(); + + nodeLocalName = nodeLocalName.replace(":", "."); + nodeLocalName = nodeLocalName.replace("-", "."); + builder.append(nodeLocalName); + } + return validateJavaPackage(builder.toString()); + } + + /** + * Generates the package name for type definition from + * typeDefinition and basePackageName. + * + * @param basePackageName + * string with the package name of the module + * @param typeDefinition + * type definition for which the package name will be generated * + * @return string with valid JAVA package name + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if typeDefinition equals null
  • + *
+ */ + public static String packageNameForTypeDefinition(final String basePackageName, + final TypeDefinition typeDefinition) { + if (basePackageName == null) { + throw new IllegalArgumentException("Base Package Name cannot be NULL!"); + } + if (typeDefinition == null) { + throw new IllegalArgumentException("Type Definition reference cannot be NULL!"); + } + + final StringBuilder builder = new StringBuilder(); + builder.append(basePackageName); + return validateJavaPackage(builder.toString()); + } + + /** + * Converts token to string which is in accordance with best + * practices for JAVA class names. + * + * @param token + * string which contains characters which should be converted to + * JAVA class name + * @return string which is in accordance with best practices for JAVA class + * name. + */ + public static String parseToClassName(String token) { + return parseToCamelCase(token, true); + } + + /** + * Converts token to string which is in accordance with best + * practices for JAVA parameter names. + * + * @param token + * string which contains characters which should be converted to + * JAVA parameter name + * @return string which is in accordance with best practices for JAVA + * parameter name. + */ + public static String parseToValidParamName(final String token) { + return resolveJavaReservedWordEquivalency(parseToCamelCase(token, false)); + } + + /** + * + * Converts string token to the cammel case format. + * + * @param token + * string which should be converted to the cammel case format + * @param uppercase + * boolean value which says whether the first character of the + * token should|shuldn't be uppercased + * @return string in the cammel case format + * @throws IllegalArgumentException + *
    + *
  • if token without white spaces is empty
  • + *
  • if token equals null
  • + *
+ */ + + private static String parseToCamelCase(final String token, final boolean uppercase) { + if (token == null) { + throw new IllegalArgumentException("Name can not be null"); + } + + String correctStr = token.trim(); + correctStr = correctStr.replace(".", ""); + + if (correctStr.isEmpty()) { + throw new IllegalArgumentException("Name can not be emty"); + } + + correctStr = replaceWithCamelCase(correctStr, ' '); + correctStr = replaceWithCamelCase(correctStr, '-'); + correctStr = replaceWithCamelCase(correctStr, '_'); + + String firstChar = correctStr.substring(0, 1); + if (uppercase) { + firstChar = firstChar.toUpperCase(); + } else { + firstChar = firstChar.toLowerCase(); + } + + if (firstChar.matches("[0-9]")) { + correctStr = "_" + correctStr; + } else { + correctStr = firstChar + correctStr.substring(1); + } + return correctStr; + } + + /** + * Replaces all the occurances of the removalChar in the + * text with empty string and converts following character to + * upper case. + * + * @param text + * string with source text which should be converted + * @param removalChar + * character which is sought in the text + * @return string which doesn't contain removalChar and has + * following characters converted to upper case + * @throws IllegalArgumentException + * if the length of the returning string has length 0 + */ + private static String replaceWithCamelCase(String text, char removalChar) { + StringBuilder sb = new StringBuilder(text); + String toBeRemoved = String.valueOf(removalChar); + + int toBeRemovedPos = sb.indexOf(toBeRemoved); + while (toBeRemovedPos != -1) { + sb.replace(toBeRemovedPos, toBeRemovedPos + 1, ""); + // check if 'toBeRemoved' character is not the only character in + // 'text' + if (sb.length() == 0) { + throw new IllegalArgumentException("The resulting string can not be empty"); + } + String replacement = String.valueOf(sb.charAt(toBeRemovedPos)).toUpperCase(); + sb.setCharAt(toBeRemovedPos, replacement.charAt(0)); + toBeRemovedPos = sb.indexOf(toBeRemoved); + } + return sb.toString(); + } + + public static long computeDefaultSUID(GeneratedTOBuilderImpl to) { + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + DataOutputStream dout = new DataOutputStream(bout); + + dout.writeUTF(to.getName()); + dout.writeInt(to.isAbstract() ? 3 : 7); + + List impl = to.getImplementsTypes(); + Collections.sort(impl, new Comparator() { + @Override + public int compare(Type o1, Type o2) { + return o1.getFullyQualifiedName().compareTo(o2.getFullyQualifiedName()); + } + }); + for (Type ifc : impl) { + dout.writeUTF(ifc.getFullyQualifiedName()); + } + + Comparator> comparator = new Comparator>() { + @Override + public int compare(TypeMemberBuilder o1, TypeMemberBuilder o2) { + return o1.getName().compareTo(o2.getName()); + } + }; + + List props = to.getProperties(); + Collections.sort(props, comparator); + for (GeneratedPropertyBuilder gp : props) { + dout.writeUTF(gp.getName()); + } + + List methods = to.getMethodDefinitions(); + Collections.sort(methods, comparator); + for (MethodSignatureBuilder m : methods) { + if (!(m.getAccessModifier().equals(AccessModifier.PRIVATE))) { + dout.writeUTF(m.getName()); + dout.write(m.getAccessModifier().ordinal()); + } + } + + dout.flush(); + + MessageDigest md = MessageDigest.getInstance("SHA"); + byte[] hashBytes = md.digest(bout.toByteArray()); + long hash = 0; + for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { + hash = (hash << 8) | (hashBytes[i] & 0xFF); + } + return hash; + } catch (IOException ex) { + throw new InternalError(); + } catch (NoSuchAlgorithmException ex) { + throw new SecurityException(ex.getMessage()); + } + } + + public static Restrictions getRestrictions(TypeDefinition type) { + final List length = new ArrayList<>(); + final List pattern = new ArrayList<>(); + final List range = new ArrayList<>(); + + if (type instanceof ExtendedType) { + ExtendedType ext = (ExtendedType)type; + TypeDefinition base = ext.getBaseType(); + length.addAll(ext.getLengthConstraints()); + pattern.addAll(ext.getPatternConstraints()); + range.addAll(ext.getRangeConstraints()); + + if (base instanceof IntegerTypeDefinition && range.isEmpty()) { + range.addAll(((IntegerTypeDefinition)base).getRangeConstraints()); + } else if (base instanceof UnsignedIntegerTypeDefinition && range.isEmpty()) { + range.addAll(((UnsignedIntegerTypeDefinition)base).getRangeConstraints()); + } else if (base instanceof DecimalTypeDefinition && range.isEmpty()) { + range.addAll(((DecimalTypeDefinition)base).getRangeConstraints()); + } + + } + + return new Restrictions() { + @Override + public List getRangeConstraints() { + return range; + } + @Override + public List getPatternConstraints() { + return pattern; + } + @Override + public List getLengthConstraints() { + return length; + } + @Override + public boolean isEmpty() { + return range.isEmpty() && pattern.isEmpty() && length.isEmpty(); + } + }; + } + +}