001/* 002Copyright (c) 2011+, HL7, Inc 003All rights reserved. 004 005Redistribution and use in source and binary forms, with or without modification, 006are permitted provided that the following conditions are met: 007 008 * Redistributions of source code must retain the above copyright notice, this 009 list of conditions and the following disclaimer. 010 * Redistributions in binary form must reproduce the above copyright notice, 011 this list of conditions and the following disclaimer in the documentation 012 and/or other materials provided with the distribution. 013 * Neither the name of HL7 nor the names of its contributors may be used to 014 endorse or promote products derived from this software without specific 015 prior written permission. 016 017THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 018ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 019WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 020IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 021INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 022NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 023PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 024WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 025ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 026POSSIBILITY OF SUCH DAMAGE. 027 028 */ 029package org.hl7.fhir.utilities; 030 031import java.io.BufferedInputStream; 032import java.io.ByteArrayInputStream; 033import java.io.ByteArrayOutputStream; 034import java.io.File; 035import java.io.FileInputStream; 036import java.io.FileNotFoundException; 037import java.io.FileOutputStream; 038import java.io.FilenameFilter; 039import java.io.IOException; 040import java.io.InputStream; 041import java.io.UnsupportedEncodingException; 042import java.math.BigDecimal; 043import java.net.URLEncoder; 044import java.nio.channels.FileChannel; 045import java.util.ArrayList; 046import java.util.List; 047import java.util.Map; 048import java.util.UUID; 049 050import javax.sound.sampled.AudioFormat; 051import javax.sound.sampled.AudioSystem; 052import javax.sound.sampled.SourceDataLine; 053import javax.xml.transform.Transformer; 054import javax.xml.transform.TransformerException; 055import javax.xml.transform.TransformerFactory; 056import javax.xml.transform.URIResolver; 057import javax.xml.transform.stream.StreamResult; 058import javax.xml.transform.stream.StreamSource; 059 060import org.apache.commons.io.FileUtils; 061import org.hl7.fhir.exceptions.FHIRException; 062 063 064public class Utilities { 065 066// private static final String TOKEN_REGEX = "^a-z[A-Za-z0-9]*$"; 067 068 private static final String OID_REGEX = "[0-2](\\.(0|[1-9][0-9]*))+"; 069 070 /** 071 * Returns the plural form of the word in the string. 072 * 073 * Examples: 074 * 075 * <pre> 076 * inflector.pluralize("post") #=> "posts" 077 * inflector.pluralize("octopus") #=> "octopi" 078 * inflector.pluralize("sheep") #=> "sheep" 079 * inflector.pluralize("words") #=> "words" 080 * inflector.pluralize("the blue mailman") #=> "the blue mailmen" 081 * inflector.pluralize("CamelOctopus") #=> "CamelOctopi" 082 * </pre> 083 * 084 * 085 * 086 * Note that if the {@link Object#toString()} is called on the supplied object, so this method works for non-strings, too. 087 * 088 * 089 * @param word the word that is to be pluralized. 090 * @return the pluralized form of the word, or the word itself if it could not be pluralized 091 * @see #singularize(Object) 092 */ 093 public static String pluralizeMe( String word ) { 094 Inflector inf = new Inflector(); 095 return inf.pluralize(word); 096 } 097 098 public static String pluralize(String word, int count) { 099 if (count == 1) 100 return word; 101 Inflector inf = new Inflector(); 102 return inf.pluralize(word); 103 } 104 105 106 public static boolean isInteger(String string) { 107 try { 108 int i = Integer.parseInt(string); 109 return i != i+1; 110 } catch (Exception e) { 111 return false; 112 } 113 } 114 115 public static boolean isHex(String string) { 116 try { 117 int i = Integer.parseInt(string, 16); 118 return i != i+1; 119 } catch (Exception e) { 120 return false; 121 } 122 } 123 124 public static boolean isFloat(String string) { 125 if (Utilities.noString(string)) 126 return false; 127 try { 128 float r = Float.parseFloat(string); 129 return r != r + 1; // just to suppress the hint 130 } catch (Exception e) { 131 return false; 132 } 133 } 134 135 public static boolean isDecimal(String string) { 136 if (Utilities.noString(string)) 137 return false; 138 try { 139 BigDecimal bd = new BigDecimal(string); 140 return bd != null; 141 } catch (Exception e) { 142 return false; 143 } 144 } 145 146 public static String camelCase(String value) { 147 return new Inflector().camelCase(value.trim().replace(" ", "_"), false); 148 } 149 150 public static String escapeXml(String doco) { 151 if (doco == null) 152 return ""; 153 154 StringBuilder b = new StringBuilder(); 155 for (char c : doco.toCharArray()) { 156 if (c == '<') 157 b.append("<"); 158 else if (c == '>') 159 b.append(">"); 160 else if (c == '&') 161 b.append("&"); 162 else if (c == '"') 163 b.append("""); 164 else 165 b.append(c); 166 } 167 return b.toString(); 168 } 169 170 public static String titleize(String s) { 171 StringBuilder b = new StringBuilder(); 172 boolean up = true; 173 for (char c : s.toCharArray()) { 174 if (up) 175 b.append(Character.toUpperCase(c)); 176 else 177 b.append(c); 178 up = c == ' '; 179 } 180 return b.toString(); 181 } 182 183 public static String capitalize(String s) 184 { 185 if( s == null ) return null; 186 if( s.length() == 0 ) return s; 187 if( s.length() == 1 ) return s.toUpperCase(); 188 189 return s.substring(0, 1).toUpperCase() + s.substring(1); 190 } 191 192 public static void copyDirectory(String sourceFolder, String destFolder, FileNotifier notifier) throws IOException, FHIRException { 193 CSFile src = new CSFile(sourceFolder); 194 if (!src.exists()) 195 throw new FHIRException("Folder " +sourceFolder+" not found"); 196 createDirectory(destFolder); 197 198 String[] files = src.list(); 199 for (String f : files) { 200 if (new CSFile(sourceFolder+File.separator+f).isDirectory()) { 201 if (!f.startsWith(".")) // ignore .git files... 202 copyDirectory(sourceFolder+File.separator+f, destFolder+File.separator+f, notifier); 203 } else { 204 if (notifier != null) 205 notifier.copyFile(sourceFolder+File.separator+f, destFolder+File.separator+f); 206 copyFile(new CSFile(sourceFolder+File.separator+f), new CSFile(destFolder+File.separator+f)); 207 } 208 } 209 } 210 211 public static void copyFile(String source, String dest) throws IOException { 212 copyFile(new File(source), new File(dest)); 213 } 214 215 public static void copyFile(File sourceFile, File destFile) throws IOException { 216 if(!destFile.exists()) { 217 if (!new CSFile(destFile.getParent()).exists()) { 218 createDirectory(destFile.getParent()); 219 } 220 destFile.createNewFile(); 221 } 222 223 FileChannel source = null; 224 FileChannel destination = null; 225 226 try { 227 source = new FileInputStream(sourceFile).getChannel(); 228 destination = new FileOutputStream(destFile).getChannel(); 229 destination.transferFrom(source, 0, source.size()); 230 } 231 finally { 232 if(source != null) { 233 source.close(); 234 } 235 if(destination != null) { 236 destination.close(); 237 } 238 } 239 } 240 241 public static boolean checkFolder(String dir, List<String> errors) 242 throws IOException 243 { 244 if (!new CSFile(dir).exists()) { 245 errors.add("Unable to find directory "+dir); 246 return false; 247 } else { 248 return true; 249 } 250 } 251 252 public static boolean checkFile(String purpose, String dir, String file, List<String> errors) 253 throws IOException 254 { 255 if (!new CSFile(dir+file).exists()) { 256 if (errors != null) 257 errors.add("Unable to find "+purpose+" file "+file+" in "+dir); 258 return false; 259 } else { 260 return true; 261 } 262 } 263 264 public static String asCSV(List<String> strings) { 265 StringBuilder s = new StringBuilder(); 266 boolean first = true; 267 for (String n : strings) { 268 if (!first) 269 s.append(","); 270 s.append(n); 271 first = false; 272 } 273 return s.toString(); 274 } 275 276 public static String asHtmlBr(String prefix, List<String> strings) { 277 StringBuilder s = new StringBuilder(); 278 boolean first = true; 279 for (String n : strings) { 280 if (!first) 281 s.append("<br/>"); 282 s.append(prefix); 283 s.append(n); 284 first = false; 285 } 286 return s.toString(); 287 } 288 289 public static void clearDirectory(String folder) throws IOException { 290 File dir = new File(folder); 291 if (dir.exists()) 292 FileUtils.cleanDirectory(dir); 293// String[] files = new CSFile(folder).list(); 294// if (files != null) { 295// for (String f : files) { 296// File fh = new CSFile(folder+File.separatorChar+f); 297// if (fh.isDirectory()) 298// clearDirectory(fh.getAbsolutePath()); 299// fh.delete(); 300// } 301// } 302 } 303 304 public static void createDirectory(String path) throws IOException{ 305 new CSFile(path).mkdirs(); 306 } 307 308 public static String changeFileExt(String name, String ext) { 309 if (name.lastIndexOf('.') > -1) 310 return name.substring(0, name.lastIndexOf('.')) + ext; 311 else 312 return name+ext; 313 } 314 315 public static String cleanupTextString( String contents ) 316 { 317 if( contents == null || contents.trim().equals("") ) 318 return null; 319 else 320 return contents.trim(); 321 } 322 323 324 public static boolean noString(String v) { 325 return v == null || v.equals(""); 326 } 327 328 329 public static byte[] transform(Map<String, byte[]> files, byte[] source, byte[] xslt) throws TransformerException { 330 TransformerFactory f = TransformerFactory.newInstance(); 331 f.setAttribute("http://saxon.sf.net/feature/version-warning", Boolean.FALSE); 332 StreamSource xsrc = new StreamSource(new ByteArrayInputStream(xslt)); 333 f.setURIResolver(new ZipURIResolver(files)); 334 Transformer t = f.newTransformer(xsrc); 335 336 t.setURIResolver(new ZipURIResolver(files)); 337 StreamSource src = new StreamSource(new ByteArrayInputStream(source)); 338 ByteArrayOutputStream out = new ByteArrayOutputStream(); 339 StreamResult res = new StreamResult(out); 340 t.transform(src, res); 341 return out.toByteArray(); 342 } 343 344 public static void bytesToFile(byte[] content, String filename) throws IOException { 345 FileOutputStream out = new FileOutputStream(filename); 346 out.write(content); 347 out.close(); 348 349 } 350 351 352 public static void transform(String xsltDir, String source, String xslt, String dest, URIResolver alt) throws FileNotFoundException, TransformerException { 353 354 TransformerFactory f = TransformerFactory.newInstance(); 355 StreamSource xsrc = new StreamSource(new FileInputStream(xslt)); 356 f.setURIResolver(new MyURIResolver(xsltDir, alt)); 357 Transformer t = f.newTransformer(xsrc); 358 359 t.setURIResolver(new MyURIResolver(xsltDir, alt)); 360 StreamSource src = new StreamSource(new FileInputStream(source)); 361 StreamResult res = new StreamResult(new FileOutputStream(dest)); 362 t.transform(src, res); 363 364 } 365 366 367 public static String appendSlash(String definitions) { 368 return definitions.endsWith(File.separator) ? definitions : definitions+File.separator; 369 } 370 371 public static String appendForwardSlash(String definitions) { 372 return definitions.endsWith("/") ? definitions : definitions+"/"; 373 } 374 375 376 public static String fileTitle(String file) { 377 if (file == null) 378 return null; 379 String s = new File(file).getName(); 380 return s.indexOf(".") == -1? s : s.substring(0, s.indexOf(".")); 381 } 382 383 384 public static String systemEol() 385 { 386 return System.getProperty("line.separator"); 387 } 388 389 public static String normaliseEolns(String value) { 390 return value.replace("\r\n", "\r").replace("\n", "\r").replace("\r", "\r\n"); 391 } 392 393 394 public static String unescapeXml(String xml) throws FHIRException { 395 if (xml == null) 396 return null; 397 398 StringBuilder b = new StringBuilder(); 399 int i = 0; 400 while (i < xml.length()) { 401 if (xml.charAt(i) == '&') { 402 StringBuilder e = new StringBuilder(); 403 i++; 404 while (xml.charAt(i) != ';') { 405 e.append(xml.charAt(i)); 406 i++; 407 } 408 if (e.toString().equals("lt")) 409 b.append("<"); 410 else if (e.toString().equals("gt")) 411 b.append(">"); 412 else if (e.toString().equals("amp")) 413 b.append("&"); 414 else if (e.toString().equals("quot")) 415 b.append("\""); 416 else if (e.toString().equals("mu")) 417 b.append((char)956); 418 else 419 throw new FHIRException("unknown XML entity \""+e.toString()+"\""); 420 } else 421 b.append(xml.charAt(i)); 422 i++; 423 } 424 return b.toString(); 425 } 426 427 428 public static boolean isPlural(String word) { 429 word = word.toLowerCase(); 430 if ("restricts".equals(word) || "contains".equals(word) || "data".equals(word) || "specimen".equals(word) || "replaces".equals(word) || "addresses".equals(word) 431 || "supplementalData".equals(word) || "instantiates".equals(word) || "imports".equals(word)) 432 return false; 433 Inflector inf = new Inflector(); 434 return !inf.singularize(word).equals(word); 435 } 436 437 438 public static String padRight(String src, char c, int len) { 439 StringBuilder s = new StringBuilder(); 440 s.append(src); 441 for (int i = 0; i < len - src.length(); i++) 442 s.append(c); 443 return s.toString(); 444 } 445 446 447 public static String padLeft(String src, char c, int len) { 448 StringBuilder s = new StringBuilder(); 449 for (int i = 0; i < len - src.length(); i++) 450 s.append(c); 451 s.append(src); 452 return s.toString(); 453 } 454 455 456 public static String path(String... args) throws IOException { 457 StringBuilder s = new StringBuilder(); 458 boolean d = false; 459 boolean first = true; 460 for(String arg: args) { 461 if (first && arg == null) 462 continue; 463 first = false; 464 if (!d) 465 d = !noString(arg); 466 else if (!s.toString().endsWith(File.separator)) 467 s.append(File.separator); 468 String a = arg; 469 if ("[tmp]".equals(a)) 470 a = System.getProperty("java.io.tmpdir"); 471 a = a.replace("\\", File.separator); 472 a = a.replace("/", File.separator); 473 if (s.length() > 0 && a.startsWith(File.separator)) 474 a = a.substring(File.separator.length()); 475 476 while (a.startsWith(".."+File.separator)) { 477 String p = s.toString().substring(0, s.length()-1); 478 if (!p.contains(File.separator)) { 479 s = new StringBuilder(); 480 } else { 481 s = new StringBuilder(p.substring(0, p.lastIndexOf(File.separator))+File.separator); 482 } 483 a = a.substring(3); 484 } 485 if ("..".equals(a)) { 486 int i = s.substring(0, s.length()-1).lastIndexOf(File.separator); 487 s = new StringBuilder(s.substring(0, i+1)); 488 } else 489 s.append(a); 490 } 491 return s.toString(); 492 } 493 494 public static String pathURL(String... args) { 495 StringBuilder s = new StringBuilder(); 496 boolean d = false; 497 for(String arg: args) { 498 if (!d) 499 d = !noString(arg); 500 else if (!s.toString().endsWith("/")) 501 s.append("/"); 502 s.append(arg); 503 } 504 return s.toString(); 505 } 506 507 508 509// public static void checkCase(String filename) { 510// File f = new CSFile(filename); 511// if (!f.getName().equals(filename)) 512// throw new FHIRException("Filename ") 513// 514// } 515 516 public static String nmtokenize(String cs) { 517 if (cs == null) 518 return ""; 519 StringBuilder s = new StringBuilder(); 520 for (int i = 0; i < cs.length(); i++) { 521 char c = cs.charAt(i); 522 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_') 523 s.append(c); 524 else if (c != ' ') 525 s.append("."+Integer.toString(c)); 526 } 527 return s.toString(); 528 } 529 530 531 public static boolean isToken(String tail) { 532 if (tail == null || tail.length() == 0) 533 return false; 534 boolean result = isAlphabetic(tail.charAt(0)); 535 for (int i = 1; i < tail.length(); i++) { 536 result = result && (isAlphabetic(tail.charAt(i)) || isDigit(tail.charAt(i)) || (tail.charAt(i) == '_') || (tail.charAt(i) == '[') || (tail.charAt(i) == ']')); 537 } 538 return result; 539 } 540 541 542 private static boolean isDigit(char c) { 543 return (c >= '0') && (c <= '9'); 544 } 545 546 547 private static boolean isAlphabetic(char c) { 548 return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); 549 } 550 551 552 public static String getDirectoryForFile(String filepath) { 553 File f = new File(filepath); 554 return f.getParent(); 555 } 556 557 public static String appendPeriod(String s) { 558 if (Utilities.noString(s)) 559 return s; 560 s = s.trim(); 561 if (s.endsWith(".") || s.endsWith("?")) 562 return s; 563 return s+"."; 564 } 565 566 567 public static String removePeriod(String s) { 568 if (Utilities.noString(s)) 569 return s; 570 if (s.endsWith(".")) 571 return s.substring(0, s.length()-1); 572 return s; 573 } 574 575 576 public static String stripBOM(String string) { 577 return string.replace("\uFEFF", ""); 578 } 579 580 581 public static String oidTail(String id) { 582 if (id == null || !id.contains(".")) 583 return id; 584 return id.substring(id.lastIndexOf(".")+1); 585 } 586 587 588 public static String oidRoot(String id) { 589 if (id == null || !id.contains(".")) 590 return id; 591 return id.substring(0, id.indexOf(".")); 592 } 593 594 public static String escapeJava(String doco) { 595 if (doco == null) 596 return ""; 597 598 StringBuilder b = new StringBuilder(); 599 for (char c : doco.toCharArray()) { 600 if (c == '\r') 601 b.append("\\r"); 602 else if (c == '\n') 603 b.append("\\n"); 604 else if (c == '"') 605 b.append("\\\""); 606 else if (c == '\\') 607 b.append("\\\\"); 608 else 609 b.append(c); 610 } 611 return b.toString(); 612 } 613 614 615 public static String[] splitByCamelCase(String name) { 616 List<String> parts = new ArrayList<String>(); 617 StringBuilder b = new StringBuilder(); 618 for (int i = 0; i < name.length(); i++) { 619 if (i > 0 && Character.isUpperCase(name.charAt(i))) { 620 parts.add(b.toString()); 621 b = new StringBuilder(); 622 } 623 b.append(Character.toLowerCase(name.charAt(i))); 624 } 625 parts.add(b.toString()); 626 return parts.toArray(new String[] {} ); 627 } 628 629 630 public static String encodeUri(String v) { 631 return v.replace(" ", "%20").replace("?", "%3F").replace("=", "%3D"); 632 } 633 634 635 636 public static String normalize(String s) { 637 if (noString(s)) 638 return null; 639 StringBuilder b = new StringBuilder(); 640 boolean isWhitespace = false; 641 for (int i = 0; i < s.length(); i++) { 642 char c = s.charAt(i); 643 if (!Character.isWhitespace(c)) { 644 b.append(Character.toLowerCase(c)); 645 isWhitespace = false; 646 } else if (!isWhitespace) { 647 b.append(' '); 648 isWhitespace = true; 649 } 650 } 651 return b.toString().trim(); 652 } 653 654 public static String normalizeSameCase(String s) { 655 if (noString(s)) 656 return null; 657 StringBuilder b = new StringBuilder(); 658 boolean isWhitespace = false; 659 for (int i = 0; i < s.length(); i++) { 660 char c = s.charAt(i); 661 if (!Character.isWhitespace(c)) { 662 b.append(c); 663 isWhitespace = false; 664 } else if (!isWhitespace) { 665 b.append(' '); 666 isWhitespace = true; 667 } 668 } 669 return b.toString().trim(); 670 } 671 672 673 public static void copyFileToDirectory(File source, File destDir) throws IOException { 674 copyFile(source, new File(path(destDir.getAbsolutePath(), source.getName()))); 675 } 676 677 678 public static boolean isWhitespace(String s) { 679 boolean ok = true; 680 for (int i = 0; i < s.length(); i++) 681 ok = ok && Character.isWhitespace(s.charAt(i)); 682 return ok; 683 684 } 685 686 687 public static String URLEncode(String string) { 688 try { 689 return URLEncoder.encode(string, "UTF-8"); 690 } catch (UnsupportedEncodingException e) { 691 throw new Error(e.getMessage()); 692 } 693 } 694 695 696 public static boolean charInSet(char value, char... array) { 697 for (int i : array) 698 if (value == i) 699 return true; 700 return false; 701 } 702 703 704 public static boolean charInRange(char ch, char a, char z) { 705 return ch >= a && ch <= z; 706 } 707 708 public static boolean existsInList(String value, String... array) { 709 if (value == null) 710 return false; 711 for (String s : array) 712 if (value.equals(s)) 713 return true; 714 return false; 715 } 716 717 public static boolean existsInList(int value, int... array) { 718 for (int i : array) 719 if (value == i) 720 return true; 721 return false; 722 } 723 724 public static boolean existsInListNC(String value, String... array) { 725 for (String s : array) 726 if (value.equalsIgnoreCase(s)) 727 return true; 728 return false; 729 } 730 731 732 public static String getFileNameForName(String name) { 733 return name.toLowerCase(); 734 } 735 736 public static void deleteTempFiles() throws IOException { 737 File file = createTempFile("test", "test"); 738 String folder = getDirectoryForFile(file.getAbsolutePath()); 739 String[] list = new File(folder).list(new FilenameFilter() { 740 public boolean accept(File dir, String name) { 741 return name.startsWith("ohfu-"); 742 } 743 }); 744 if (list != null) { 745 for (String n : list) { 746 new File(path(folder, n)).delete(); 747 } 748 } 749 } 750 751 public static File createTempFile(String prefix, String suffix) throws IOException { 752 // this allows use to eaily identify all our dtemp files and delete them, since delete on Exit doesn't really work. 753 File file = File.createTempFile("ohfu-"+prefix, suffix); 754 file.deleteOnExit(); 755 return file; 756 } 757 758 759 public static boolean isAsciiChar(char ch) { 760 return ch >= ' ' && ch <= '~'; 761 } 762 763 764 public static String makeUuidUrn() { 765 return "urn:uuid:"+UUID.randomUUID().toString().toLowerCase(); 766 } 767 768 public static boolean isURL(String s) { 769 boolean ok = s.matches("^http(s{0,1})://[a-zA-Z0-9_/\\-\\.]+\\.([A-Za-z/]{2,5})[a-zA-Z0-9_/\\&\\?\\=\\-\\.\\~\\%]*"); 770 return ok; 771 } 772 773 774 public static String escapeJson(String value) { 775 if (value == null) 776 return ""; 777 778 StringBuilder b = new StringBuilder(); 779 for (char c : value.toCharArray()) { 780 if (c == '\r') 781 b.append("\\r"); 782 else if (c == '\n') 783 b.append("\\n"); 784 else if (c == '\t') 785 b.append("\\t"); 786 else if (c == '"') 787 b.append("\\\""); 788 else if (c == '\\') 789 b.append("\\\\"); 790 else if (((int) c) < 32) 791 b.append("\\u"+Utilities.padLeft(String.valueOf((int) c), '0', 4)); 792 else 793 b.append(c); 794 } 795 return b.toString(); 796 } 797 798 public static String humanize(String code) { 799 StringBuilder b = new StringBuilder(); 800 boolean lastBreak = true; 801 for (char c : code.toCharArray()) { 802 if (Character.isLetter(c)) { 803 if (lastBreak) 804 b.append(Character.toUpperCase(c)); 805 else { 806 if (Character.isUpperCase(c)) 807 b.append(" "); 808 b.append(c); 809 } 810 lastBreak = false; 811 } else { 812 b.append(" "); 813 lastBreak = true; 814 } 815 } 816 if (b.length() == 0) 817 return code; 818 else 819 return b.toString(); 820 } 821 822 823 public static String uncapitalize(String s) { 824 if( s == null ) return null; 825 if( s.length() == 0 ) return s; 826 if( s.length() == 1 ) return s.toLowerCase(); 827 828 return s.substring(0, 1).toLowerCase() + s.substring(1); 829 } 830 831 832 public static int charCount(String s, char c) { 833 int res = 0; 834 for (char ch : s.toCharArray()) 835 if (ch == c) 836 res++; 837 return res; 838 } 839 840 841 // http://stackoverflow.com/questions/3780406/how-to-play-a-sound-alert-in-a-java-application 842 public static float SAMPLE_RATE = 8000f; 843 844 public static void tone(int hz, int msecs) { 845 tone(hz, msecs, 1.0); 846 } 847 848 public static void tone(int hz, int msecs, double vol) { 849 try { 850 byte[] buf = new byte[1]; 851 AudioFormat af = 852 new AudioFormat( 853 SAMPLE_RATE, // sampleRate 854 8, // sampleSizeInBits 855 1, // channels 856 true, // signed 857 false); // bigEndian 858 SourceDataLine sdl; 859 sdl = AudioSystem.getSourceDataLine(af); 860 sdl.open(af); 861 sdl.start(); 862 for (int i=0; i < msecs*8; i++) { 863 double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI; 864 buf[0] = (byte)(Math.sin(angle) * 127.0 * vol); 865 sdl.write(buf,0,1); 866 } 867 sdl.drain(); 868 sdl.stop(); 869 sdl.close(); 870 } catch (Exception e) { 871 } 872 } 873 874 875 public static boolean isOid(String cc) { 876 return cc.matches(OID_REGEX) && cc.lastIndexOf('.') >= 5; 877 } 878 879 880 public static boolean equals(String one, String two) { 881 if (one == null && two == null) 882 return true; 883 if (one == null || two == null) 884 return false; 885 return one.equals(two); 886 } 887 888 889 public static void deleteAllFiles(String folder, String type) { 890 File src = new File(folder); 891 String[] files = src.list(); 892 for (String f : files) { 893 if (new File(folder+File.separator+f).isDirectory()) { 894 deleteAllFiles(folder+File.separator+f, type); 895 } else if (f.endsWith(type)) { 896 new File(folder+File.separator+f).delete(); 897 } 898 } 899 900 } 901 902 public static boolean compareIgnoreWhitespace(File f1, File f2) throws IOException { 903 InputStream in1 = null; 904 InputStream in2 = null; 905 try { 906 in1 = new BufferedInputStream(new FileInputStream(f1)); 907 in2 = new BufferedInputStream(new FileInputStream(f2)); 908 909 int expectedByte = in1.read(); 910 while (expectedByte != -1) { 911 boolean w1 = isWhitespace(expectedByte); 912 if (w1) 913 while (isWhitespace(expectedByte)) 914 expectedByte = in1.read(); 915 int foundByte = in2.read(); 916 if (w1) { 917 if (!isWhitespace(foundByte)) 918 return false; 919 while (isWhitespace(foundByte)) 920 foundByte = in2.read(); 921 } 922 if (expectedByte != foundByte) 923 return false; 924 expectedByte = in1.read(); 925 } 926 if (in2.read() != -1) { 927 return false; 928 } 929 return true; 930 } finally { 931 if (in1 != null) { 932 try { 933 in1.close(); 934 } catch (IOException e) {} 935 } 936 if (in2 != null) { 937 try { 938 in2.close(); 939 } catch (IOException e) {} 940 } 941 } 942 } 943 944 private static boolean isWhitespace(int b) { 945 return b == 9 || b == 10 || b == 13 || b == 32; 946 } 947 948 949 public static boolean compareIgnoreWhitespace(String fn1, String fn2) throws IOException { 950 return compareIgnoreWhitespace(new File(fn1), new File(fn2)); 951 } 952 953 954 public static boolean isAbsoluteUrl(String ref) { 955 return ref != null && (ref.startsWith("http:") || ref.startsWith("https:") || ref.startsWith("urn:uuid:") || ref.startsWith("urn:oid:")) ; 956 } 957 958 959 public static boolean equivalent(String l, String r) { 960 if (Utilities.noString(l) && Utilities.noString(r)) 961 return true; 962 if (Utilities.noString(l) || Utilities.noString(r)) 963 return false; 964 return l.toLowerCase().equals(r.toLowerCase()); 965 } 966 967 968 public static boolean equivalentNumber(String l, String r) { 969 if (Utilities.noString(l) && Utilities.noString(r)) 970 return true; 971 if (Utilities.noString(l) || Utilities.noString(r)) 972 return false; 973 l = l.toLowerCase().trim(); 974 r = r.toLowerCase().trim(); // not that this should make any difference 975 return l.startsWith(r) || r.startsWith(l); 976 } 977 978 979 public static String getFileExtension(String fn) { 980 return fn.contains(".") ? fn.substring(fn.lastIndexOf(".")+1) : ""; 981 } 982 983 984 public static String unCamelCase(String name) { 985 StringBuilder b = new StringBuilder(); 986 boolean first = true; 987 for (char c : name.toCharArray()) { 988 if (Character.isUpperCase(c)) { 989 if (!first) 990 b.append(" "); 991 b.append(Character.toLowerCase(c)); 992 } else 993 b.append(c); 994 first = false; 995 } 996 return b.toString(); 997 } 998 999 1000 public static boolean isAbsoluteFileName(String source) { 1001 if (isWindows()) 1002 return (source.length() > 2 && source.charAt(1) == ':') || source.startsWith("\\\\"); 1003 else 1004 return source.startsWith("//"); 1005 } 1006 1007 1008 public static boolean isWindows() { 1009 return System.getProperty("os.name").startsWith("Windows"); 1010 } 1011 1012 1013 public static String splitLineForLength(String line, int prefixLength, int indent, int allowedLength) { 1014 List<String> list = new ArrayList<String>(); 1015 while (prefixLength + line.length() > allowedLength) { 1016 int i = allowedLength - (list.size() == 0 ? prefixLength : indent); 1017 while (i > 0 && line.charAt(i) != ' ') 1018 i--; 1019 if (i == 0) 1020 break; 1021 list.add(line.substring(0, i)); 1022 line = line.substring(i+1); 1023 } 1024 list.add(line); 1025 StringBuilder b = new StringBuilder(); 1026 boolean first = true; 1027 for (String s : list) { 1028 if (first) 1029 first = false; 1030 else 1031 b.append("\r\n"+padLeft("", ' ', indent)); 1032 b.append(s); 1033 } 1034 return b.toString(); 1035 } 1036 1037 1038 public static int countFilesInDirectory(String dirName) { 1039 File dir = new File(dirName); 1040 if (dir.exists() == false) { 1041 return 0; 1042 } 1043 int i = 0; 1044 for (File f : dir.listFiles()) 1045 if (!f.isDirectory()) 1046 i++; 1047 return i; 1048 } 1049 1050 public static String makeId(String name) { 1051 StringBuilder b = new StringBuilder(); 1052 for (char ch : name.toCharArray()) { 1053 if (ch >= 'a' && ch <= 'z') 1054 b.append(ch); 1055 else if (ch >= 'A' && ch <= 'Z') 1056 b.append(ch); 1057 else if (ch >= '0' && ch <= '9') 1058 b.append(ch); 1059 else if (ch == '-' || ch == '.') 1060 b.append(ch); 1061 } 1062 return b.toString(); 1063 } 1064 1065 public interface FileVisitor { 1066 void visitFile(File file) throws FileNotFoundException, IOException; 1067 } 1068 1069 public static void visitFiles(String folder, String extension, FileVisitor visitor) throws FileNotFoundException, IOException { 1070 visitFiles(new File(folder), extension, visitor); 1071 } 1072 1073 public static void visitFiles(File folder, String extension, FileVisitor visitor) throws FileNotFoundException, IOException { 1074 for (File file : folder.listFiles()) { 1075 if (file.isDirectory()) 1076 visitFiles(file, extension, visitor); 1077 else if (extension == null || file.getName().endsWith(extension)) 1078 visitor.visitFile(file); 1079 } 1080 } 1081 1082 1083}