diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java index ff67156dd0d..137418f00b0 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3Test.java @@ -3314,7 +3314,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test { } public static void assertConflictException(ResourceVersionConflictException e) { - assertThat(e.getMessage(), matchesPattern("Unable to delete Observation/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource Observation/[0-9]+ in path DiagnosticReport.result")); + assertThat(e.getMessage(), matchesPattern("Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+")); } private static List toStringList(List theUriType) { diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml index 67a7580d16d..76ba10285e7 100644 --- a/hapi-fhir-structures-dstu3/pom.xml +++ b/hapi-fhir-structures-dstu3/pom.xml @@ -39,19 +39,19 @@ - - xpp3 xpp3_min 1.1.4c + + diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/utilities/Inflector.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/utilities/Inflector.java deleted file mode 100644 index 06e11326900..00000000000 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/utilities/Inflector.java +++ /dev/null @@ -1,619 +0,0 @@ -/* -Copyright (c) 2011+, HL7, Inc -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ -package org.hl7.fhir.utilities; - -/* - * JBoss DNA (http://www.jboss.org/dna) - * See the COPYRIGHT.txt file distributed with this work for information - * regarding copyright ownership. Some portions may be licensed - * to Red Hat, Inc. under one or more contributor license agreements. - * See the AUTHORS.txt file in the distribution for a full listing of - * individual contributors. - * - * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA - * is licensed to you under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * JBoss DNA is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Transforms words to singular, plural, humanized (human readable), underscore, camel case, or ordinal form. This is inspired by - * the Inflector class in Ruby on Rails, which is distributed under the Rails license. - * - * @author Randall Hauch - */ -public class Inflector { - - protected static final Inflector INSTANCE = new Inflector(); - - public static final Inflector getInstance() { - return INSTANCE; - } - - protected class Rule { - - protected final String expression; - protected final Pattern expressionPattern; - protected final String replacement; - - protected Rule( String expression, - String replacement ) { - this.expression = expression; - this.replacement = replacement != null ? replacement : ""; - this.expressionPattern = Pattern.compile(this.expression, Pattern.CASE_INSENSITIVE); - } - - /** - * Apply the rule against the input string, returning the modified string or null if the rule didn't apply (and no - * modifications were made) - * - * @param input the input string - * @return the modified string if this rule applied, or null if the input was not modified by this rule - */ - protected String apply( String input ) { - Matcher matcher = this.expressionPattern.matcher(input); - if (!matcher.find()) return null; - return matcher.replaceAll(this.replacement); - } - - @Override - public int hashCode() { - return expression.hashCode(); - } - - @Override - public boolean equals( Object obj ) { - if (obj == this) return true; - if (obj != null && obj.getClass() == this.getClass()) { - final Rule that = (Rule)obj; - if (this.expression.equalsIgnoreCase(that.expression)) return true; - } - return false; - } - - @Override - public String toString() { - return expression + ", " + replacement; - } - } - - private LinkedList plurals = new LinkedList(); - private LinkedList singulars = new LinkedList(); - /** - * The lowercase words that are to be excluded and not processed. This map can be modified by the users via - * {@link #getUncountables()}. - */ - private final Set uncountables = new HashSet(); - - public Inflector() { - initialize(); - } - - protected Inflector( Inflector original ) { - this.plurals.addAll(original.plurals); - this.singulars.addAll(original.singulars); - this.uncountables.addAll(original.uncountables); - } - - @Override - public Inflector clone() { - return new Inflector(this); - } - - // ------------------------------------------------------------------------------------------------ - // Usage functions - // ------------------------------------------------------------------------------------------------ - - /** - * Returns the plural form of the word in the string. - * - * Examples: - * - *
-     *   inflector.pluralize("post")               #=> "posts"
-     *   inflector.pluralize("octopus")            #=> "octopi"
-     *   inflector.pluralize("sheep")              #=> "sheep"
-     *   inflector.pluralize("words")              #=> "words"
-     *   inflector.pluralize("the blue mailman")   #=> "the blue mailmen"
-     *   inflector.pluralize("CamelOctopus")       #=> "CamelOctopi"
-     * 
- * - * - * - * Note that if the {@link Object#toString()} is called on the supplied object, so this method works for non-strings, too. - * - * - * @param word the word that is to be pluralized. - * @return the pluralized form of the word, or the word itself if it could not be pluralized - * @see #singularize(Object) - */ - public String pluralize( Object word ) { - if (word == null) return null; - String wordStr = word.toString().trim(); - if (wordStr.length() == 0) return wordStr; - if (isUncountable(wordStr)) return wordStr; - for (Rule rule : this.plurals) { - String result = rule.apply(wordStr); - if (result != null) return result; - } - return wordStr; - } - - public String pluralize( Object word, - int count ) { - if (word == null) return null; - if (count == 1 || count == -1) { - return word.toString(); - } - return pluralize(word); - } - - /** - * Returns the singular form of the word in the string. - * - * Examples: - * - *
-     *   inflector.singularize("posts")             #=> "post"
-     *   inflector.singularize("octopi")            #=> "octopus"
-     *   inflector.singularize("sheep")             #=> "sheep"
-     *   inflector.singularize("words")             #=> "word"
-     *   inflector.singularize("the blue mailmen")  #=> "the blue mailman"
-     *   inflector.singularize("CamelOctopi")       #=> "CamelOctopus"
-     * 
- * - * - * - * Note that if the {@link Object#toString()} is called on the supplied object, so this method works for non-strings, too. - * - * - * @param word the word that is to be pluralized. - * @return the pluralized form of the word, or the word itself if it could not be pluralized - * @see #pluralize(Object) - */ - public String singularize( Object word ) { - if (word == null) return null; - String wordStr = word.toString().trim(); - if (wordStr.length() == 0) return wordStr; - if (isUncountable(wordStr)) return wordStr; - for (Rule rule : this.singulars) { - String result = rule.apply(wordStr); - if (result != null) return result; - } - return wordStr; - } - - /** - * Converts strings to lowerCamelCase. This method will also use any extra delimiter characters to identify word boundaries. - * - * Examples: - * - *
-     *   inflector.lowerCamelCase("active_record")       #=> "activeRecord"
-     *   inflector.lowerCamelCase("first_name")          #=> "firstName"
-     *   inflector.lowerCamelCase("name")                #=> "name"
-     *   inflector.lowerCamelCase("the-first_name",'-')  #=> "theFirstName"
-     * 
- * - * - * - * @param lowerCaseAndUnderscoredWord the word that is to be converted to camel case - * @param delimiterChars optional characters that are used to delimit word boundaries - * @return the lower camel case version of the word - * @see #underscore(String, char[]) - * @see #camelCase(String, boolean, char[]) - * @see #upperCamelCase(String, char[]) - */ - public String lowerCamelCase( String lowerCaseAndUnderscoredWord, - char... delimiterChars ) { - return camelCase(lowerCaseAndUnderscoredWord, false, delimiterChars); - } - - /** - * Converts strings to UpperCamelCase. This method will also use any extra delimiter characters to identify word boundaries. - * - * Examples: - * - *
-     *   inflector.upperCamelCase("active_record")       #=> "SctiveRecord"
-     *   inflector.upperCamelCase("first_name")          #=> "FirstName"
-     *   inflector.upperCamelCase("name")                #=> "Name"
-     *   inflector.lowerCamelCase("the-first_name",'-')  #=> "TheFirstName"
-     * 
- * - * - * - * @param lowerCaseAndUnderscoredWord the word that is to be converted to camel case - * @param delimiterChars optional characters that are used to delimit word boundaries - * @return the upper camel case version of the word - * @see #underscore(String, char[]) - * @see #camelCase(String, boolean, char[]) - * @see #lowerCamelCase(String, char[]) - */ - public String upperCamelCase( String lowerCaseAndUnderscoredWord, - char... delimiterChars ) { - return camelCase(lowerCaseAndUnderscoredWord, true, delimiterChars); - } - - /** - * By default, this method converts strings to UpperCamelCase. If the uppercaseFirstLetter argument to false, - * then this method produces lowerCamelCase. This method will also use any extra delimiter characters to identify word - * boundaries. - * - * Examples: - * - *
-     *   inflector.camelCase("active_record",false)    #=> "activeRecord"
-     *   inflector.camelCase("active_record",true)     #=> "ActiveRecord"
-     *   inflector.camelCase("first_name",false)       #=> "firstName"
-     *   inflector.camelCase("first_name",true)        #=> "FirstName"
-     *   inflector.camelCase("name",false)             #=> "name"
-     *   inflector.camelCase("name",true)              #=> "Name"
-     * 
- * - * - * - * @param lowerCaseAndUnderscoredWord the word that is to be converted to camel case - * @param uppercaseFirstLetter true if the first character is to be uppercased, or false if the first character is to be - * lowercased - * @param delimiterChars optional characters that are used to delimit word boundaries - * @return the camel case version of the word - * @see #underscore(String, char[]) - * @see #upperCamelCase(String, char[]) - * @see #lowerCamelCase(String, char[]) - */ - public String camelCase( String lowerCaseAndUnderscoredWord, - boolean uppercaseFirstLetter, - char... delimiterChars ) { - if (lowerCaseAndUnderscoredWord == null) return null; - lowerCaseAndUnderscoredWord = lowerCaseAndUnderscoredWord.trim(); - if (lowerCaseAndUnderscoredWord.length() == 0) return ""; - if (uppercaseFirstLetter) { - String result = lowerCaseAndUnderscoredWord; - // Replace any extra delimiters with underscores (before the underscores are converted in the next step)... - if (delimiterChars != null) { - for (char delimiterChar : delimiterChars) { - result = result.replace(delimiterChar, '_'); - } - } - - // Change the case at the beginning at after each underscore ... - return replaceAllWithUppercase(result, "(^|_)(.)", 2); - } - if (lowerCaseAndUnderscoredWord.length() < 2) return lowerCaseAndUnderscoredWord; - return "" + Character.toLowerCase(lowerCaseAndUnderscoredWord.charAt(0)) - + camelCase(lowerCaseAndUnderscoredWord, true, delimiterChars).substring(1); - } - - /** - * Makes an underscored form from the expression in the string (the reverse of the {@link #camelCase(String, boolean, char[]) - * camelCase} method. Also changes any characters that match the supplied delimiters into underscore. - * - * Examples: - * - *
-     *   inflector.underscore("activeRecord")     #=> "active_record"
-     *   inflector.underscore("ActiveRecord")     #=> "active_record"
-     *   inflector.underscore("firstName")        #=> "first_name"
-     *   inflector.underscore("FirstName")        #=> "first_name"
-     *   inflector.underscore("name")             #=> "name"
-     *   inflector.underscore("The.firstName")    #=> "the_first_name"
-     * 
- * - * - * - * @param camelCaseWord the camel-cased word that is to be converted; - * @param delimiterChars optional characters that are used to delimit word boundaries (beyond capitalization) - * @return a lower-cased version of the input, with separate words delimited by the underscore character. - */ - public String underscore( String camelCaseWord, - char... delimiterChars ) { - if (camelCaseWord == null) return null; - String result = camelCaseWord.trim(); - if (result.length() == 0) return ""; - result = result.replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2"); - result = result.replaceAll("([a-z\\d])([A-Z])", "$1_$2"); - result = result.replace('-', '_'); - if (delimiterChars != null) { - for (char delimiterChar : delimiterChars) { - result = result.replace(delimiterChar, '_'); - } - } - return result.toLowerCase(); - } - - /** - * Returns a copy of the input with the first character converted to uppercase and the remainder to lowercase. - * - * @param words the word to be capitalized - * @return the string with the first character capitalized and the remaining characters lowercased - */ - public String capitalize( String words ) { - if (words == null) return null; - String result = words.trim(); - if (result.length() == 0) return ""; - if (result.length() == 1) return result.toUpperCase(); - return "" + Character.toUpperCase(result.charAt(0)) + result.substring(1).toLowerCase(); - } - - /** - * Capitalizes the first word and turns underscores into spaces and strips trailing "_id" and any supplied removable tokens. - * Like {@link #titleCase(String, String[])}, this is meant for creating pretty output. - * - * Examples: - * - *
-     *   inflector.humanize("employee_salary")       #=> "Employee salary"
-     *   inflector.humanize("author_id")             #=> "Author"
-     * 
- * - * - * - * @param lowerCaseAndUnderscoredWords the input to be humanized - * @param removableTokens optional array of tokens that are to be removed - * @return the humanized string - * @see #titleCase(String, String[]) - */ - public String humanize( String lowerCaseAndUnderscoredWords, - String... removableTokens ) { - if (lowerCaseAndUnderscoredWords == null) return null; - String result = lowerCaseAndUnderscoredWords.trim(); - if (result.length() == 0) return ""; - // Remove a trailing "_id" token - result = result.replaceAll("_id$", ""); - // Remove all of the tokens that should be removed - if (removableTokens != null) { - for (String removableToken : removableTokens) { - result = result.replaceAll(removableToken, ""); - } - } - result = result.replaceAll("_+", " "); // replace all adjacent underscores with a single space - return capitalize(result); - } - - /** - * Capitalizes all the words and replaces some characters in the string to create a nicer looking title. Underscores are - * changed to spaces, a trailing "_id" is removed, and any of the supplied tokens are removed. Like - * {@link #humanize(String, String[])}, this is meant for creating pretty output. - * - * Examples: - * - *
-     *   inflector.titleCase("man from the boondocks")       #=> "Man From The Boondocks"
-     *   inflector.titleCase("x-men: the last stand")        #=> "X Men: The Last Stand"
-     * 
- * - * - * - * @param words the input to be turned into title case - * @param removableTokens optional array of tokens that are to be removed - * @return the title-case version of the supplied words - */ - public String titleCase( String words, - String... removableTokens ) { - String result = humanize(words, removableTokens); - result = replaceAllWithUppercase(result, "\\b([a-z])", 1); // change first char of each word to uppercase - return result; - } - - /** - * Turns a non-negative number into an ordinal string used to denote the position in an ordered sequence, such as 1st, 2nd, - * 3rd, 4th. - * - * @param number the non-negative number - * @return the string with the number and ordinal suffix - */ - public String ordinalize( int number ) { - int remainder = number % 100; - String numberStr = Integer.toString(number); - if (11 <= number && number <= 13) return numberStr + "th"; - remainder = number % 10; - if (remainder == 1) return numberStr + "st"; - if (remainder == 2) return numberStr + "nd"; - if (remainder == 3) return numberStr + "rd"; - return numberStr + "th"; - } - - // ------------------------------------------------------------------------------------------------ - // Management methods - // ------------------------------------------------------------------------------------------------ - - /** - * Determine whether the supplied word is considered uncountable by the {@link #pluralize(Object) pluralize} and - * {@link #singularize(Object) singularize} methods. - * - * @param word the word - * @return true if the plural and singular forms of the word are the same - */ - public boolean isUncountable( String word ) { - if (word == null) return false; - String trimmedLower = word.trim().toLowerCase(); - return this.uncountables.contains(trimmedLower); - } - - /** - * Get the set of words that are not processed by the Inflector. The resulting map is directly modifiable. - * - * @return the set of uncountable words - */ - public Set getUncountables() { - return uncountables; - } - - public void addPluralize( String rule, - String replacement ) { - final Rule pluralizeRule = new Rule(rule, replacement); - this.plurals.addFirst(pluralizeRule); - } - - public void addSingularize( String rule, - String replacement ) { - final Rule singularizeRule = new Rule(rule, replacement); - this.singulars.addFirst(singularizeRule); - } - - public void addIrregular( String singular, - String plural ) { - //CheckArg.isNotEmpty(singular, "singular rule"); - //CheckArg.isNotEmpty(plural, "plural rule"); - String singularRemainder = singular.length() > 1 ? singular.substring(1) : ""; - String pluralRemainder = plural.length() > 1 ? plural.substring(1) : ""; - addPluralize("(" + singular.charAt(0) + ")" + singularRemainder + "$", "$1" + pluralRemainder); - addSingularize("(" + plural.charAt(0) + ")" + pluralRemainder + "$", "$1" + singularRemainder); - } - - public void addUncountable( String... words ) { - if (words == null || words.length == 0) return; - for (String word : words) { - if (word != null) uncountables.add(word.trim().toLowerCase()); - } - } - - /** - * Utility method to replace all occurrences given by the specific backreference with its uppercased form, and remove all - * other backreferences. - * - * The Java {@link Pattern regular expression processing} does not use the preprocessing directives \l, - * \u, \L, and \U. If so, such directives could be used in the replacement string - * to uppercase or lowercase the backreferences. For example, \L1 would lowercase the first backreference, and - * \u3 would uppercase the 3rd backreference. - * - * - * @param input - * @param regex - * @param groupNumberToUppercase - * @return the input string with the appropriate characters converted to upper-case - */ - protected static String replaceAllWithUppercase( String input, - String regex, - int groupNumberToUppercase ) { - Pattern underscoreAndDotPattern = Pattern.compile(regex); - Matcher matcher = underscoreAndDotPattern.matcher(input); - StringBuffer sb = new StringBuffer(); - while (matcher.find()) { - matcher.appendReplacement(sb, matcher.group(groupNumberToUppercase).toUpperCase()); - } - matcher.appendTail(sb); - return sb.toString(); - } - - /** - * Completely remove all rules within this inflector. - */ - public void clear() { - this.uncountables.clear(); - this.plurals.clear(); - this.singulars.clear(); - } - - protected void initialize() { - Inflector inflect = this; - inflect.addPluralize("$", "s"); - inflect.addPluralize("s$", "s"); - inflect.addPluralize("(ax|test)is$", "$1es"); - inflect.addPluralize("(octop|vir)us$", "$1i"); - inflect.addPluralize("(octop|vir)i$", "$1i"); // already plural - inflect.addPluralize("(alias|status)$", "$1es"); - inflect.addPluralize("(bu)s$", "$1ses"); - inflect.addPluralize("(buffal|tomat)o$", "$1oes"); - inflect.addPluralize("([ti])um$", "$1a"); - inflect.addPluralize("([ti])a$", "$1a"); // already plural - inflect.addPluralize("sis$", "ses"); - inflect.addPluralize("(?:([^f])fe|([lr])f)$", "$1$2ves"); - inflect.addPluralize("(hive)$", "$1s"); - inflect.addPluralize("([^aeiouy]|qu)y$", "$1ies"); - inflect.addPluralize("(x|ch|ss|sh)$", "$1es"); - inflect.addPluralize("(matr|vert|ind)ix|ex$", "$1ices"); - inflect.addPluralize("([m|l])ouse$", "$1ice"); - inflect.addPluralize("([m|l])ice$", "$1ice"); - inflect.addPluralize("^(ox)$", "$1en"); - inflect.addPluralize("(quiz)$", "$1zes"); - // Need to check for the following words that are already pluralized: - inflect.addPluralize("(people|men|children|sexes|moves|stadiums)$", "$1"); // irregulars - inflect.addPluralize("(oxen|octopi|viri|aliases|quizzes)$", "$1"); // special rules - - inflect.addSingularize("s$", ""); - inflect.addSingularize("(s|si|u)s$", "$1s"); // '-us' and '-ss' are already singular - inflect.addSingularize("(n)ews$", "$1ews"); - inflect.addSingularize("([ti])a$", "$1um"); - inflect.addSingularize("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis"); - inflect.addSingularize("(^analy)ses$", "$1sis"); - inflect.addSingularize("(^analy)sis$", "$1sis"); // already singular, but ends in 's' - inflect.addSingularize("([^f])ves$", "$1fe"); - inflect.addSingularize("(hive)s$", "$1"); - inflect.addSingularize("(tive)s$", "$1"); - inflect.addSingularize("([lr])ves$", "$1f"); - inflect.addSingularize("([^aeiouy]|qu)ies$", "$1y"); - inflect.addSingularize("(s)eries$", "$1eries"); - inflect.addSingularize("(m)ovies$", "$1ovie"); - inflect.addSingularize("(x|ch|ss|sh)es$", "$1"); - inflect.addSingularize("([m|l])ice$", "$1ouse"); - inflect.addSingularize("(bus)es$", "$1"); - inflect.addSingularize("(o)es$", "$1"); - inflect.addSingularize("(shoe)s$", "$1"); - inflect.addSingularize("(cris|ax|test)is$", "$1is"); // already singular, but ends in 's' - inflect.addSingularize("(cris|ax|test)es$", "$1is"); - inflect.addSingularize("(octop|vir)i$", "$1us"); - inflect.addSingularize("(octop|vir)us$", "$1us"); // already singular, but ends in 's' - inflect.addSingularize("(alias|status)es$", "$1"); - inflect.addSingularize("(alias|status)$", "$1"); // already singular, but ends in 's' - inflect.addSingularize("^(ox)en", "$1"); - inflect.addSingularize("(vert|ind)ices$", "$1ex"); - inflect.addSingularize("(matr)ices$", "$1ix"); - inflect.addSingularize("(quiz)zes$", "$1"); - - inflect.addIrregular("person", "people"); - inflect.addIrregular("man", "men"); - inflect.addIrregular("child", "children"); - inflect.addIrregular("sex", "sexes"); - inflect.addIrregular("move", "moves"); - inflect.addIrregular("stadium", "stadiums"); - - inflect.addUncountable("equipment", "information", "rice", "money", "species", "series", "fish", "sheep"); - } - -} \ No newline at end of file diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/utilities/Utilities.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/utilities/Utilities.java index abf0f52ab13..d7bd4eee669 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/utilities/Utilities.java +++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/utilities/Utilities.java @@ -1,961 +1,213 @@ -/* -Copyright (c) 2011+, HL7, Inc -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - */ -package org.hl7.fhir.utilities; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.channels.FileChannel; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.SourceDataLine; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.URIResolver; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import net.sf.saxon.TransformerFactoryImpl; - -import org.apache.commons.io.FileUtils; -import org.hl7.fhir.exceptions.FHIRException; - -public class Utilities { - -// private static final String TOKEN_REGEX = "^a-z[A-Za-z0-9]*$"; - - - private static final String OID_REGEX = "[0-2](\\.(0|[1-9]([0-9])*))*"; - - /** - * Returns the plural form of the word in the string. - * - * Examples: - * - *
-     *   inflector.pluralize("post")               #=> "posts"
-     *   inflector.pluralize("octopus")            #=> "octopi"
-     *   inflector.pluralize("sheep")              #=> "sheep"
-     *   inflector.pluralize("words")              #=> "words"
-     *   inflector.pluralize("the blue mailman")   #=> "the blue mailmen"
-     *   inflector.pluralize("CamelOctopus")       #=> "CamelOctopi"
-     * 
- * - * - * - * Note that if the {@link Object#toString()} is called on the supplied object, so this method works for non-strings, too. - * - * - * @param word the word that is to be pluralized. - * @return the pluralized form of the word, or the word itself if it could not be pluralized - * @see #singularize(Object) - */ - public static String pluralizeMe( String word ) { - Inflector inf = new Inflector(); - return inf.pluralize(word); - } - - - public static boolean isInteger(String string) { - try { - int i = Integer.parseInt(string); - return i != i+1; - } catch (Exception e) { - return false; - } - } - - public static boolean isHex(String string) { - try { - int i = Integer.parseInt(string, 16); - return i != i+1; - } catch (Exception e) { - return false; - } - } - - public static boolean isDecimal(String string) { - try { - float r = Float.parseFloat(string); - return r != r + 1; // just to suppress the hint - } catch (Exception e) { - return false; - } - } - - public static String camelCase(String value) { - return new Inflector().camelCase(value.trim().replace(" ", "_"), false); - } - - public static String escapeXml(String doco) { - if (doco == null) - return ""; - - StringBuilder b = new StringBuilder(); - for (char c : doco.toCharArray()) { - if (c == '<') - b.append("<"); - else if (c == '>') - b.append(">"); - else if (c == '&') - b.append("&"); - else if (c == '"') - b.append("""); - else - b.append(c); - } - return b.toString(); - } - - - public static String capitalize(String s) - { - if( s == null ) return null; - if( s.length() == 0 ) return s; - if( s.length() == 1 ) return s.toUpperCase(); - - return s.substring(0, 1).toUpperCase() + s.substring(1); - } - - public static void copyDirectory(String sourceFolder, String destFolder, FileNotifier notifier) throws IOException, FHIRException { - CSFile src = new CSFile(sourceFolder); - if (!src.exists()) - throw new FHIRException("Folder " +sourceFolder+" not found"); - createDirectory(destFolder); - - String[] files = src.list(); - for (String f : files) { - if (new CSFile(sourceFolder+File.separator+f).isDirectory()) { - if (!f.startsWith(".")) // ignore .svn... - copyDirectory(sourceFolder+File.separator+f, destFolder+File.separator+f, notifier); - } else { - if (notifier != null) - notifier.copyFile(sourceFolder+File.separator+f, destFolder+File.separator+f); - copyFile(new CSFile(sourceFolder+File.separator+f), new CSFile(destFolder+File.separator+f)); - } - } - } - - public static void copyFile(String source, String dest) throws IOException { - copyFile(new File(source), new File(dest)); - } - - public static void copyFile(File sourceFile, File destFile) throws IOException { - if(!destFile.exists()) { - if (!new CSFile(destFile.getParent()).exists()) { - createDirectory(destFile.getParent()); - } - destFile.createNewFile(); - } - - FileChannel source = null; - FileChannel destination = null; - - try { - source = new FileInputStream(sourceFile).getChannel(); - destination = new FileOutputStream(destFile).getChannel(); - destination.transferFrom(source, 0, source.size()); - } - finally { - if(source != null) { - source.close(); - } - if(destination != null) { - destination.close(); - } - } - } - - public static boolean checkFolder(String dir, List errors) - throws IOException - { - if (!new CSFile(dir).exists()) { - errors.add("Unable to find directory "+dir); - return false; - } else { - return true; - } - } - - public static boolean checkFile(String purpose, String dir, String file, List errors) - throws IOException - { - if (!new CSFile(dir+file).exists()) { - errors.add("Unable to find "+purpose+" file "+file+" in "+dir); - return false; - } else { - return true; - } - } - - public static String asCSV(List strings) { - StringBuilder s = new StringBuilder(); - boolean first = true; - for (String n : strings) { - if (!first) - s.append(","); - s.append(n); - first = false; - } - return s.toString(); - } - - public static String asHtmlBr(String prefix, List strings) { - StringBuilder s = new StringBuilder(); - boolean first = true; - for (String n : strings) { - if (!first) - s.append("
"); - s.append(prefix); - s.append(n); - first = false; - } - return s.toString(); - } - - public static void clearDirectory(String folder) throws IOException { - File dir = new File(folder); - if (dir.exists()) - FileUtils.cleanDirectory(dir); -// String[] files = new CSFile(folder).list(); -// if (files != null) { -// for (String f : files) { -// File fh = new CSFile(folder+File.separatorChar+f); -// if (fh.isDirectory()) -// clearDirectory(fh.getAbsolutePath()); -// fh.delete(); -// } -// } - } - - public static void createDirectory(String path) throws IOException{ - new CSFile(path).mkdirs(); - } - - public static String changeFileExt(String name, String ext) { - if (name.lastIndexOf('.') > -1) - return name.substring(0, name.lastIndexOf('.')) + ext; - else - return name+ext; - } - - public static String cleanupTextString( String contents ) - { - if( contents == null || contents.trim().equals("") ) - return null; - else - return contents.trim(); - } - - - public static boolean noString(String v) { - return v == null || v.equals(""); - } - - - public static byte[] saxonTransform(Map files, byte[] source, byte[] xslt) throws TransformerException { - TransformerFactory f = new net.sf.saxon.TransformerFactoryImpl(); - f.setAttribute("http://saxon.sf.net/feature/version-warning", Boolean.FALSE); - StreamSource xsrc = new StreamSource(new ByteArrayInputStream(xslt)); - f.setURIResolver(new ZipURIResolver(files)); - Transformer t = f.newTransformer(xsrc); - - t.setURIResolver(new ZipURIResolver(files)); - StreamSource src = new StreamSource(new ByteArrayInputStream(source)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - StreamResult res = new StreamResult(out); - t.transform(src, res); - return out.toByteArray(); - } - - public static byte[] transform(Map files, byte[] source, byte[] xslt) throws TransformerException { - TransformerFactory f = TransformerFactory.newInstance(); - f.setAttribute("http://saxon.sf.net/feature/version-warning", Boolean.FALSE); - StreamSource xsrc = new StreamSource(new ByteArrayInputStream(xslt)); - f.setURIResolver(new ZipURIResolver(files)); - Transformer t = f.newTransformer(xsrc); - - t.setURIResolver(new ZipURIResolver(files)); - StreamSource src = new StreamSource(new ByteArrayInputStream(source)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - StreamResult res = new StreamResult(out); - t.transform(src, res); - return out.toByteArray(); - } - - public static void bytesToFile(byte[] content, String filename) throws IOException { - FileOutputStream out = new FileOutputStream(filename); - out.write(content); - out.close(); - - } - - public static String saxonTransform(String source, String xslt) throws TransformerException, FileNotFoundException { - TransformerFactoryImpl f = new net.sf.saxon.TransformerFactoryImpl(); - f.setAttribute("http://saxon.sf.net/feature/version-warning", Boolean.FALSE); - StreamSource xsrc = new StreamSource(new FileInputStream(xslt)); - Transformer t = f.newTransformer(xsrc); - StreamSource src = new StreamSource(new FileInputStream(source)); - StreamResult res = new StreamResult(new ByteArrayOutputStream()); - t.transform(src, res); - return res.getOutputStream().toString(); - } - - public static void saxonTransform(String xsltDir, String source, String xslt, String dest, URIResolver alt) throws FileNotFoundException, TransformerException { - saxonTransform(xsltDir, source, xslt, dest, alt, null); - } - - public static void saxonTransform(String xsltDir, String source, String xslt, String dest, URIResolver alt, Map params) throws FileNotFoundException, TransformerException { - TransformerFactoryImpl f = new net.sf.saxon.TransformerFactoryImpl(); - f.setAttribute("http://saxon.sf.net/feature/version-warning", Boolean.FALSE); - StreamSource xsrc = new StreamSource(new FileInputStream(xslt)); - f.setURIResolver(new MyURIResolver(xsltDir, alt)); - Transformer t = f.newTransformer(xsrc); - if (params != null) { - for (Map.Entry entry : params.entrySet()) { - t.setParameter(entry.getKey(), entry.getValue()); - } - } - - t.setURIResolver(new MyURIResolver(xsltDir, alt)); - StreamSource src = new StreamSource(new FileInputStream(source)); - StreamResult res = new StreamResult(new FileOutputStream(dest)); - t.transform(src, res); - } - - public static void transform(String xsltDir, String source, String xslt, String dest, URIResolver alt) throws FileNotFoundException, TransformerException { - - TransformerFactory f = TransformerFactory.newInstance(); - StreamSource xsrc = new StreamSource(new FileInputStream(xslt)); - f.setURIResolver(new MyURIResolver(xsltDir, alt)); - Transformer t = f.newTransformer(xsrc); - - t.setURIResolver(new MyURIResolver(xsltDir, alt)); - StreamSource src = new StreamSource(new FileInputStream(source)); - StreamResult res = new StreamResult(new FileOutputStream(dest)); - t.transform(src, res); - - } - - - public static String appendSlash(String definitions) { - return definitions.endsWith(File.separator) ? definitions : definitions+File.separator; - } - - public static String appendForwardSlash(String definitions) { - return definitions.endsWith("/") ? definitions : definitions+"/"; - } - - - public static String fileTitle(String file) { - if (file == null) - return null; - String s = new File(file).getName(); - return s.indexOf(".") == -1? s : s.substring(0, s.indexOf(".")); - } - - - public static String systemEol() - { - return System.getProperty("line.separator"); - } - - public static String normaliseEolns(String value) { - return value.replace("\r\n", "\r").replace("\n", "\r").replace("\r", "\r\n"); - } - - - public static String unescapeXml(String xml) throws FHIRException { - if (xml == null) - return null; - - StringBuilder b = new StringBuilder(); - int i = 0; - while (i < xml.length()) { - if (xml.charAt(i) == '&') { - StringBuilder e = new StringBuilder(); - i++; - while (xml.charAt(i) != ';') { - e.append(xml.charAt(i)); - i++; - } - if (e.toString().equals("lt")) - b.append("<"); - else if (e.toString().equals("gt")) - b.append(">"); - else if (e.toString().equals("amp")) - b.append("&"); - else if (e.toString().equals("quot")) - b.append("\""); - else if (e.toString().equals("mu")) - b.append((char)956); - else - throw new FHIRException("unknown XML entity \""+e.toString()+"\""); - } else - b.append(xml.charAt(i)); - i++; - } - return b.toString(); - } - - - public static boolean isPlural(String word) { - word = word.toLowerCase(); - if ("restricts".equals(word) || "contains".equals(word) || "data".equals(word) || "specimen".equals(word)) - return false; - Inflector inf = new Inflector(); - return !inf.singularize(word).equals(word); - } - - - public static String padLeft(String src, char c, int len) { - StringBuilder s = new StringBuilder(); - for (int i = 0; i < len - src.length(); i++) - s.append(c); - s.append(src); - return s.toString(); - - } - - - public static String path(String... args) { - StringBuilder s = new StringBuilder(); - boolean d = false; - for(String arg: args) { - if (!d) - d = !noString(arg); - else if (!s.toString().endsWith(File.separator)) - s.append(File.separator); - String a = arg; - a = a.replace("\\", File.separator); - if (s.length() > 0 && a.startsWith(File.separator)) - a = a.substring(File.separator.length()); - - if ("..".equals(a)) { - int i = s.substring(0, s.length()-1).lastIndexOf(File.separator); - s = new StringBuilder(s.substring(0, i+1)); - } else - s.append(a); - } - return s.toString(); - } - - public static String pathReverse(String... args) { - StringBuilder s = new StringBuilder(); - boolean d = false; - for(String arg: args) { - if (!d) - d = !noString(arg); - else if (!s.toString().endsWith("/")) - s.append("/"); - s.append(arg); - } - return s.toString(); - } - - - -// public static void checkCase(String filename) { -// File f = new CSFile(filename); -// if (!f.getName().equals(filename)) -// throw new FHIRException("Filename ") -// -// } - - public static String nmtokenize(String cs) { - StringBuilder s = new StringBuilder(); - for (int i = 0; i < cs.length(); i++) { - char c = cs.charAt(i); - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_') - s.append(c); - else if (c != ' ') - s.append("."+Integer.toString(c)); - } - return s.toString(); - } - - - public static boolean isToken(String tail) { - if (tail == null || tail.length() == 0) - return false; - boolean result = isAlphabetic(tail.charAt(0)); - for (int i = 1; i < tail.length(); i++) { - result = result && (isAlphabetic(tail.charAt(i)) || isDigit(tail.charAt(i)) || (tail.charAt(i) == '_') || (tail.charAt(i) == '[') || (tail.charAt(i) == ']')); - } - return result; - } - - - private static boolean isDigit(char c) { - return (c >= '0') && (c <= '9'); - } - - - private static boolean isAlphabetic(char c) { - return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); - } - - - public static String getDirectoryForFile(String filepath) { - File f = new File(filepath); - return f.getParent(); - } - - public static String appendPeriod(String s) { - if (Utilities.noString(s)) - return s; - s = s.trim(); - if (s.endsWith(".") || s.endsWith("?")) - return s; - return s+"."; - } - - - public static String removePeriod(String s) { - if (Utilities.noString(s)) - return s; - if (s.endsWith(".")) - return s.substring(0, s.length()-1); - return s; - } - - - public static String stripBOM(String string) { - return string.replace("\uFEFF", ""); - } - - - public static String oidTail(String id) { - if (id == null || !id.contains(".")) - return id; - return id.substring(id.lastIndexOf(".")+1); - } - - - public static String oidRoot(String id) { - if (id == null || !id.contains(".")) - return id; - return id.substring(0, id.indexOf(".")); - } - - public static String escapeJava(String doco) { - if (doco == null) - return ""; - - StringBuilder b = new StringBuilder(); - for (char c : doco.toCharArray()) { - if (c == '\r') - b.append("\\r"); - else if (c == '\n') - b.append("\\n"); - else if (c == '"') - b.append("\\\""); - else if (c == '\\') - b.append("\\\\"); - else - b.append(c); - } - return b.toString(); - } - - - public static String[] splitByCamelCase(String name) { - List parts = new ArrayList(); - StringBuilder b = new StringBuilder(); - for (int i = 0; i < name.length(); i++) { - if (i > 0 && Character.isUpperCase(name.charAt(i))) { - parts.add(b.toString()); - b = new StringBuilder(); - } - b.append(Character.toLowerCase(name.charAt(i))); - } - parts.add(b.toString()); - return parts.toArray(new String[] {} ); - } - - - public static String encodeUri(String v) { - return v.replace(" ", "%20").replace("?", "%3F").replace("=", "%3D"); - } - - - - public static String normalize(String s) { - if (noString(s)) - return null; - StringBuilder b = new StringBuilder(); - boolean isWhitespace = false; - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (!Character.isWhitespace(c)) { - b.append(Character.toLowerCase(c)); - isWhitespace = false; - } else if (!isWhitespace) { - b.append(' '); - isWhitespace = true; - } - } - return b.toString().trim(); - } - - public static String normalizeSameCase(String s) { - if (noString(s)) - return null; - StringBuilder b = new StringBuilder(); - boolean isWhitespace = false; - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (!Character.isWhitespace(c)) { - b.append(c); - isWhitespace = false; - } else if (!isWhitespace) { - b.append(' '); - isWhitespace = true; - } - } - return b.toString().trim(); - } - - - public static void copyFileToDirectory(File source, File destDir) throws IOException { - copyFile(source, new File(path(destDir.getAbsolutePath(), source.getName()))); - } - - - public static boolean isWhitespace(String s) { - boolean ok = true; - for (int i = 0; i < s.length(); i++) - ok = ok && Character.isWhitespace(s.charAt(i)); - return ok; - - } - - - public static String URLEncode(String string) { - try { - return URLEncoder.encode(string, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new Error(e.getMessage()); - } - } - - - public static boolean charInSet(char value, char... array) { - for (int i : array) - if (value == i) - return true; - return false; - } - - public static boolean existsInList(String value, String... array) { - if (value == null) - return false; - for (String s : array) - if (value.equals(s)) - return true; - return false; - } - - public static boolean existsInList(int value, int... array) { - for (int i : array) - if (value == i) - return true; - return false; - } - - public static boolean existsInListNC(String value, String... array) { - for (String s : array) - if (value.equalsIgnoreCase(s)) - return true; - return false; - } - - - public static String getFileNameForName(String name) { - return name.toLowerCase(); - } - - public static void deleteTempFiles() throws IOException { - File file = createTempFile("test", "test"); - String folder = getDirectoryForFile(file.getAbsolutePath()); - String[] list = new File(folder).list(new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith("ohfu-"); - } - }); - if (list != null) { - for (String n : list) { - new File(path(folder, n)).delete(); - } - } - } - - public static File createTempFile(String prefix, String suffix) throws IOException { - // this allows use to eaily identify all our dtemp files and delete them, since delete on Exit doesn't really work. - File file = File.createTempFile("ohfu-"+prefix, suffix); - file.deleteOnExit(); - return file; - } - - - public static boolean isAsciiChar(char ch) { - return ch >= ' ' && ch <= '~'; - } - - - public static String makeUuidUrn() { - return "urn:uuid:"+UUID.randomUUID().toString().toLowerCase(); - } - - public static boolean isURL(String s) { - boolean ok = s.matches("^http(s{0,1})://[a-zA-Z0-9_/\\-\\.]+\\.([A-Za-z/]{2,5})[a-zA-Z0-9_/\\&\\?\\=\\-\\.\\~\\%]*"); - return ok; - } - - - public static String escapeJson(String value) { - if (value == null) - return ""; - - StringBuilder b = new StringBuilder(); - for (char c : value.toCharArray()) { - if (c == '\r') - b.append("\\r"); - else if (c == '\n') - b.append("\\n"); - else if (c == '"') - b.append("\\\""); - else if (c == '\'') - b.append("\\'"); - else if (c == '\\') - b.append("\\\\"); - else - b.append(c); - } - return b.toString(); - } - - public static String humanize(String code) { - StringBuilder b = new StringBuilder(); - boolean lastBreak = true; - for (char c : code.toCharArray()) { - if (Character.isLetter(c)) { - if (lastBreak) - b.append(Character.toUpperCase(c)); - else { - if (Character.isUpperCase(c)) - b.append(" "); - b.append(c); - } - lastBreak = false; - } else { - b.append(" "); - lastBreak = true; - } - } - if (b.length() == 0) - return code; - else - return b.toString(); - } - - - public static String uncapitalize(String s) { - if( s == null ) return null; - if( s.length() == 0 ) return s; - if( s.length() == 1 ) return s.toLowerCase(); - - return s.substring(0, 1).toLowerCase() + s.substring(1); - } - - - public static int charCount(String s, char c) { - int res = 0; - for (char ch : s.toCharArray()) - if (ch == c) - res++; - return res; - } - - - // http://stackoverflow.com/questions/3780406/how-to-play-a-sound-alert-in-a-java-application - public static float SAMPLE_RATE = 8000f; - - public static void tone(int hz, int msecs) { - tone(hz, msecs, 1.0); - } - - public static void tone(int hz, int msecs, double vol) { - try { - byte[] buf = new byte[1]; - AudioFormat af = - new AudioFormat( - SAMPLE_RATE, // sampleRate - 8, // sampleSizeInBits - 1, // channels - true, // signed - false); // bigEndian - SourceDataLine sdl; - sdl = AudioSystem.getSourceDataLine(af); - sdl.open(af); - sdl.start(); - for (int i=0; i < msecs*8; i++) { - double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI; - buf[0] = (byte)(Math.sin(angle) * 127.0 * vol); - sdl.write(buf,0,1); - } - sdl.drain(); - sdl.stop(); - sdl.close(); - } catch (Exception e) { - } - } - - - public static boolean isOid(String cc) { - return cc.matches(OID_REGEX) && cc.lastIndexOf('.') > 5; - } - - - public static boolean equals(String one, String two) { - if (one == null && two == null) - return true; - if (one == null || two == null) - return false; - return one.equals(two); - } - - - public static void deleteAllFiles(String folder, String type) { - File src = new File(folder); - String[] files = src.list(); - for (String f : files) { - if (new File(folder+File.separator+f).isDirectory()) { - deleteAllFiles(folder+File.separator+f, type); - } else if (f.endsWith(type)) { - new File(folder+File.separator+f).delete(); - } - } - - } - - public static boolean compareIgnoreWhitespace(File f1, File f2) throws IOException { - InputStream in1 = null; - InputStream in2 = null; - try { - in1 = new BufferedInputStream(new FileInputStream(f1)); - in2 = new BufferedInputStream(new FileInputStream(f2)); - - int expectedByte = in1.read(); - while (expectedByte != -1) { - boolean w1 = isWhitespace(expectedByte); - if (w1) - while (isWhitespace(expectedByte)) - expectedByte = in1.read(); - int foundByte = in2.read(); - if (w1) { - if (!isWhitespace(foundByte)) - return false; - while (isWhitespace(foundByte)) - foundByte = in2.read(); - } - if (expectedByte != foundByte) - return false; - expectedByte = in1.read(); - } - if (in2.read() != -1) { - return false; - } - return true; - } finally { - if (in1 != null) { - try { - in1.close(); - } catch (IOException e) {} - } - if (in2 != null) { - try { - in2.close(); - } catch (IOException e) {} - } - } - } - - private static boolean isWhitespace(int b) { - return b == 9 || b == 10 || b == 13 || b == 32; - } - - - public static boolean compareIgnoreWhitespace(String fn1, String fn2) throws IOException { - return compareIgnoreWhitespace(new File(fn1), new File(fn2)); - } - - - public static boolean isAbsoluteUrl(String ref) { - return ref.startsWith("http:") || ref.startsWith("https:") || ref.startsWith("urn:uuid:") || ref.startsWith("urn:oid:") ; - } - - - public static boolean equivalent(String l, String r) { - if (Utilities.noString(l) && Utilities.noString(r)) - return true; - if (Utilities.noString(l) || Utilities.noString(r)) - return false; - return l.toLowerCase().equals(r.toLowerCase()); - } - - - public static boolean equivalentNumber(String l, String r) { - if (Utilities.noString(l) && Utilities.noString(r)) - return true; - if (Utilities.noString(l) || Utilities.noString(r)) - return false; - l = l.toLowerCase().trim(); - r = r.toLowerCase().trim(); // not that this should make any difference - return l.startsWith(r) || r.startsWith(l); - } - - -} +package org.hl7.fhir.utilities; + +import static org.apache.commons.lang3.StringUtils.isBlank; + +import java.io.File; + +public class Utilities { + + public static String appendSlash(String definitions) { + return definitions.endsWith(File.separator) ? definitions : definitions + File.separator; + } + + public static String capitalize(String s) { + if (s == null) + return null; + if (s.length() == 0) + return s; + if (s.length() == 1) + return s.toUpperCase(); + + return s.substring(0, 1).toUpperCase() + s.substring(1); + } + + public static boolean charInSet(char value, char... array) { + for (int i : array) + if (value == i) + return true; + return false; + } + + public static boolean equivalent(String l, String r) { + if (noString(l) && noString(r)) + return true; + if (noString(l) || noString(r)) + return false; + return l.toLowerCase().equals(r.toLowerCase()); + } + + public static boolean equivalentNumber(String l, String r) { + if (noString(l) && noString(r)) + return true; + if (noString(l) || noString(r)) + return false; + l = l.toLowerCase().trim(); + r = r.toLowerCase().trim(); // not that this should make any difference + return l.startsWith(r) || r.startsWith(l); + } + + public static String escapeJava(String doco) { + if (doco == null) + return ""; + + StringBuilder b = new StringBuilder(); + for (char c : doco.toCharArray()) { + if (c == '\r') + b.append("\\r"); + else if (c == '\n') + b.append("\\n"); + else if (c == '"') + b.append("\\\""); + else if (c == '\\') + b.append("\\\\"); + else + b.append(c); + } + return b.toString(); + } + + public static String escapeXml(String doco) { + if (doco == null) + return ""; + + StringBuilder b = new StringBuilder(); + for (char c : doco.toCharArray()) { + if (c == '<') + b.append("<"); + else if (c == '>') + b.append(">"); + else if (c == '&') + b.append("&"); + else if (c == '"') + b.append("""); + else + b.append(c); + } + return b.toString(); + } + + public static boolean existsInList(int value, int... array) { + for (int i : array) + if (value == i) + return true; + return false; + } + + public static boolean existsInList(String value, String... array) { + if (value == null) + return false; + for (String s : array) + if (value.equals(s)) + return true; + return false; + } + + public static boolean isAbsoluteUrl(String ref) { + return ref.startsWith("http:") || ref.startsWith("https:") || ref.startsWith("urn:uuid:") || ref.startsWith("urn:oid:"); + } + + public static boolean isDecimal(String string) { + try { + float r = Float.parseFloat(string); + return r != r + 1; // just to suppress the hint + } catch (Exception e) { + return false; + } + } + + public static boolean isHex(String string) { + try { + int i = Integer.parseInt(string, 16); + return i != i + 1; + } catch (Exception e) { + return false; + } + } + + public static boolean isInteger(String string) { + try { + int i = Integer.parseInt(string); + return i != i + 1; + } catch (Exception e) { + return false; + } + } + + public static String normalize(String s) { + if (noString(s)) + return null; + StringBuilder b = new StringBuilder(); + boolean isWhitespace = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (!Character.isWhitespace(c)) { + b.append(Character.toLowerCase(c)); + isWhitespace = false; + } else if (!isWhitespace) { + b.append(' '); + isWhitespace = true; + } + } + return b.toString().trim(); + } + + public static boolean noString(String theValue) { + return isBlank(theValue); + } + + public static String padLeft(String src, char c, int len) { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < len - src.length(); i++) + s.append(c); + s.append(src); + return s.toString(); + + } + + public static String path(String... args) { + StringBuilder s = new StringBuilder(); + boolean d = false; + for (String arg : args) { + if (!d) + d = !noString(arg); + else if (!s.toString().endsWith(File.separator)) + s.append(File.separator); + String a = arg; + a = a.replace("\\", File.separator); + if (s.length() > 0 && a.startsWith(File.separator)) + a = a.substring(File.separator.length()); + + if ("..".equals(a)) { + int i = s.substring(0, s.length() - 1).lastIndexOf(File.separator); + s = new StringBuilder(s.substring(0, i + 1)); + } else + s.append(a); + } + return s.toString(); + } + + public static String pathReverse(String... args) { + StringBuilder s = new StringBuilder(); + boolean d = false; + for (String arg : args) { + if (!d) + d = !noString(arg); + else if (!s.toString().endsWith("/")) + s.append("/"); + s.append(arg); + } + return s.toString(); + } + + public static String uncapitalize(String s) { + if (s == null) + return null; + if (s.length() == 0) + return s; + if (s.length() == 1) + return s.toLowerCase(); + + return s.substring(0, 1).toLowerCase() + s.substring(1); + } + +} diff --git a/hapi-fhir-structures-dstu3/todo.txt b/hapi-fhir-structures-dstu3/todo.txt new file mode 100644 index 00000000000..064e25a7c74 --- /dev/null +++ b/hapi-fhir-structures-dstu3/todo.txt @@ -0,0 +1 @@ +Move use of Saxon and Inflector out of Utilities.java (saxon isn't needed and Inflector has GPL license) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 5eb2c15ffbe..cb76c2fda5a 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -28,6 +28,10 @@ Conditional URLs in JPA server (e.g. for delete or update) did not support the _has]]> parameter + + Remove Maven dependency on Saxon library, as it is not actually used. Thanks + to Lem Edmondson for the suggestion! +