1 21 22 package org.apache.derby.impl.load; 23 24 import java.io.BufferedReader ; 25 import java.io.FileNotFoundException ; 26 import java.io.InputStream ; 27 import java.io.InputStreamReader ; 28 import java.io.FileInputStream ; 29 import java.io.IOException ; 30 import java.net.MalformedURLException ; 31 import java.net.URL ; 32 import org.apache.derby.iapi.services.sanity.SanityManager; 33 34 final class ImportReadData implements java.security.PrivilegedExceptionAction { 35 private String inputFileName; 37 38 private int[] columnWidths; 39 private int rowWidth; 40 private char[] tempString; 41 private int numberOfCharsReadSoFar; 42 43 private BufferedReader bufferedReader; 45 46 private static final int START_SIZE = 10240; 48 private char[] currentToken = new char[START_SIZE]; 49 private int currentTokenMaxSize = START_SIZE; 50 51 boolean foundStartDelimiter; 53 int totalCharsSoFar; 54 int positionOfNonWhiteSpaceCharInFront; 56 int positionOfNonWhiteSpaceCharInBack; 58 int lineNumber; 59 int fieldStartDelimiterIndex; 60 int fieldStopDelimiterIndex; 61 int stopDelimiterPosition; 62 boolean foundStartAndStopDelimiters; 63 64 boolean streamOpenForReading; 70 71 static final int DEFAULT_FORMAT_CODE = 0; 72 static final int ASCII_FIXED_FORMAT_CODE = 1; 73 private int formatCode = DEFAULT_FORMAT_CODE; 74 private boolean hasColumnDefinition; 75 private char recordSeparatorChar0; 76 private char fieldSeparatorChar0; 77 private boolean recordSepStartNotWhite = true; 78 private boolean fieldSepStartNotWhite = true; 79 80 protected ControlInfo controlFileReader; 82 83 protected int numberOfColumns; 86 87 protected String [] columnTypes; 89 90 protected char[] fieldSeparator; 92 protected int fieldSeparatorLength; 93 protected char[] recordSeparator; 94 protected int recordSeparatorLength; 95 protected String nullString; 96 protected String columnDefinition; 97 protected String format; 98 protected String dataCodeset; 99 protected char[] fieldStartDelimiter; 100 protected int fieldStartDelimiterLength; 101 protected char[] fieldStopDelimiter; 102 protected int fieldStopDelimiterLength; 103 protected boolean hasDelimiterAtEnd; 104 105 106 private void loadPropertiesInfo() throws Exception { 109 fieldSeparator = controlFileReader.getFieldSeparator().toCharArray(); 110 fieldSeparatorLength = fieldSeparator.length; 111 recordSeparator = controlFileReader.getRecordSeparator().toCharArray(); 112 recordSeparatorLength = recordSeparator.length; 113 nullString = controlFileReader.getNullString(); 114 columnDefinition = controlFileReader.getColumnDefinition(); 115 format = controlFileReader.getFormat(); 116 dataCodeset = controlFileReader.getDataCodeset(); 117 fieldStartDelimiter = controlFileReader.getFieldStartDelimiter().toCharArray(); 118 fieldStartDelimiterLength = fieldStartDelimiter.length; 119 fieldStopDelimiter = controlFileReader.getFieldEndDelimiter().toCharArray(); 120 fieldStopDelimiterLength = fieldStopDelimiter.length; 121 hasDelimiterAtEnd = controlFileReader.getHasDelimiterAtEnd(); 122 123 if (recordSeparatorLength >0) { 127 recordSeparatorChar0=recordSeparator[0]; 128 recordSepStartNotWhite = (Character.isWhitespace(recordSeparatorChar0)==false); 129 } 130 if (fieldSeparatorLength >0) { 131 fieldSeparatorChar0=fieldSeparator[0]; 132 fieldSepStartNotWhite = (Character.isWhitespace(fieldSeparatorChar0)==false); 133 } 134 } 135 ImportReadData(String inputFileName, ControlInfo controlFileReader) 138 throws Exception { 139 this.inputFileName = inputFileName; 140 this.controlFileReader = controlFileReader; 141 142 loadPropertiesInfo(); 145 loadMetaData(); 148 } 149 150 int getNumberOfColumns() { 152 return numberOfColumns; 153 } 154 158 protected void ignoreFirstRow() throws Exception { 159 readNextToken(recordSeparator, 0, recordSeparatorLength, true); 160 } 161 162 165 protected void loadColumnTypes() throws Exception { 166 int idx; 167 String [] metaDataArray; 168 169 findNumberOfColumnsInARow(); 172 173 closeStream(); 175 openFile(); 176 177 metaDataArray=new String [numberOfColumns]; 179 180 readNextDelimitedRow(metaDataArray); 182 183 columnTypes=new String [numberOfColumns/2]; 188 189 for(idx=0 ; idx<numberOfColumns ; idx=idx+2) { 190 columnTypes[idx/2]=metaDataArray[idx+1]; 191 } 192 193 194 closeStream(); 197 openFile(); 198 199 numberOfColumns=0; 202 } 203 204 private void openFile() throws Exception { 205 try { 206 java.security.AccessController.doPrivileged(this); 207 } catch (java.security.PrivilegedActionException pae) { 208 throw pae.getException(); 209 } 210 } 211 212 public final Object run() throws Exception { 213 realOpenFile(); 214 return null; 215 } 216 217 private void realOpenFile() throws Exception { 219 InputStream inputStream; 220 try { 221 try { 222 URL url = new URL (inputFileName); 223 if (url.getProtocol().equals("file")) { inputFileName = url.getFile(); throw new MalformedURLException (); } 227 inputStream = url.openStream(); 228 } catch (MalformedURLException ex) { 229 inputStream = new FileInputStream (inputFileName); 230 231 } 232 } catch (FileNotFoundException ex) { 233 throw LoadError.dataFileNotFound(inputFileName); 234 } catch (SecurityException se) { 235 java.sql.SQLException sqle = LoadError.dataFileNotFound(inputFileName); 236 237 sqle.setNextException(new java.sql.SQLException ("XJ001", se.getMessage(), 0)); 238 239 throw sqle; 240 } 241 java.io.Reader rd = dataCodeset == null ? 242 new InputStreamReader (inputStream) : new InputStreamReader (inputStream, dataCodeset); 243 bufferedReader = new BufferedReader (rd, 32*1024); 244 streamOpenForReading = true; 245 } 246 247 private void loadMetaData() throws Exception { 250 openFile(); 252 if (columnDefinition.toUpperCase(java.util.Locale.ENGLISH).equals(ControlInfo.INTERNAL_TRUE.toUpperCase(java.util.Locale.ENGLISH))) { 256 hasColumnDefinition = true; 257 ignoreFirstRow(); 258 } 259 260 if (formatCode == DEFAULT_FORMAT_CODE) { 261 findNumberOfColumnsInARow(); 262 } 263 closeStream(); 264 } 265 266 269 void closeStream() throws Exception { 270 if (streamOpenForReading) { 271 bufferedReader.close(); 272 streamOpenForReading = false; 273 } 274 } 275 276 int findNumberOfColumnsInARow() throws Exception { 278 numberOfColumns=1; 281 while (! readTokensUntilEndOfRecord() ) { 282 numberOfColumns++; 283 } 284 288 if (hasDelimiterAtEnd){ 291 --numberOfColumns; 292 } 293 294 if (numberOfCharsReadSoFar==0) { 297 numberOfColumns=0; 298 } 299 return numberOfColumns; 300 } 301 302 private void checkForWhiteSpaceInFront() { 310 if ((positionOfNonWhiteSpaceCharInFront + 1) == totalCharsSoFar && 312 ((!foundStartDelimiter) && (!foundStartAndStopDelimiters) )) { 313 char currentChar = currentToken[positionOfNonWhiteSpaceCharInFront]; 314 if ( Character.isWhitespace(currentChar) == true) { 325 326 if ((recordSepStartNotWhite || (currentChar != recordSeparatorChar0)) 327 && 328 (fieldSepStartNotWhite || (currentChar != fieldSeparatorChar0))) 329 positionOfNonWhiteSpaceCharInFront++; 331 } 332 } 333 } 334 335 336 private void checkForWhiteSpaceInBack() { 341 boolean onlyWhiteSpaceSoFar = true; 342 positionOfNonWhiteSpaceCharInBack = 0; 343 344 for (int i = totalCharsSoFar; (i > stopDelimiterPosition) && onlyWhiteSpaceSoFar; i--) { 345 char currentChar = currentToken[i]; 346 if (Character.isWhitespace(currentChar)==true) { 351 352 if ((recordSepStartNotWhite || (currentChar != recordSeparatorChar0)) 353 && 354 (fieldSepStartNotWhite || (currentChar != fieldSeparatorChar0))) 355 positionOfNonWhiteSpaceCharInBack++; 357 } else 358 onlyWhiteSpaceSoFar = false; 359 } 360 } 361 362 boolean readTokensUntilEndOfRecord() throws Exception { 366 int nextChar; 367 int fieldSeparatorIndex = 0; 368 int recordSeparatorIndex = 0; 369 370 fieldStopDelimiterIndex = 0; 371 fieldStartDelimiterIndex = 0; 372 totalCharsSoFar = 0; 373 positionOfNonWhiteSpaceCharInFront = 0; 375 foundStartDelimiter = false; 376 foundStartAndStopDelimiters = false; 377 numberOfCharsReadSoFar = 0; 378 379 while (true) { 380 nextChar = bufferedReader.read(); 381 if (nextChar == -1) 382 return true; 383 numberOfCharsReadSoFar++; 384 currentToken[totalCharsSoFar++] = (char)nextChar; 387 checkForWhiteSpaceInFront(); 389 if (totalCharsSoFar == currentTokenMaxSize) { 390 currentTokenMaxSize = currentTokenMaxSize * 2; 391 char[] tempArray = new char[currentTokenMaxSize]; 392 System.arraycopy(currentToken, 0, tempArray, 0, totalCharsSoFar); 393 currentToken = tempArray; 394 } 395 396 fieldSeparatorIndex = lookForPassedSeparator(fieldSeparator, 398 fieldSeparatorIndex, 399 fieldSeparatorLength, 400 nextChar, false); 401 if (fieldSeparatorIndex == -1) 405 return false; 406 407 if (!foundStartDelimiter ) { 410 recordSeparatorIndex = lookForPassedSeparator(recordSeparator, recordSeparatorIndex, 412 recordSeparatorLength, nextChar, true); 413 if (recordSeparatorIndex == -1) 414 return true; 415 } 416 } 417 } 418 419 private int lookForPassedSeparator(char[] delimiter, int delimiterIndex, 423 int delimiterLength, int nextChar, 424 boolean lookForRecordSeperator) throws 425 IOException 426 { 427 428 if (!foundStartDelimiter ) { 433 if (fieldStartDelimiterLength != 0 && (!foundStartAndStopDelimiters) ) { 436 if (totalCharsSoFar != positionOfNonWhiteSpaceCharInFront && 439 (totalCharsSoFar - positionOfNonWhiteSpaceCharInFront) <= fieldStartDelimiterLength) { 440 if (nextChar == fieldStartDelimiter[fieldStartDelimiterIndex]){ 443 fieldStartDelimiterIndex++; 444 if (fieldStartDelimiterIndex == fieldStartDelimiterLength) { 445 foundStartDelimiter = true; 446 totalCharsSoFar = 0; 448 positionOfNonWhiteSpaceCharInFront = 0; 449 return 0; 450 } 451 } else { 452 if (fieldStartDelimiterIndex > 0) { 457 reCheckRestOfTheCharacters(totalCharsSoFar-fieldStartDelimiterIndex, 458 fieldStartDelimiter, fieldStartDelimiterLength); 459 } 460 } 461 } 462 } 463 464 467 if(lookForRecordSeperator) 468 { 469 if(nextChar == '\r' || nextChar == '\n') 470 { 471 recordSeparatorChar0 = (char) nextChar; 472 if(nextChar == '\r' ) 473 { 474 omitLineFeed(); 476 } 477 478 totalCharsSoFar = totalCharsSoFar - 1 ; 479 return -1; 480 } 481 482 return delimiterIndex; 483 } 484 485 if (nextChar == delimiter[delimiterIndex]) { 487 delimiterIndex++; 488 if (delimiterIndex == delimiterLength) { totalCharsSoFar = totalCharsSoFar - delimiterLength; 490 return -1; 491 } 492 return delimiterIndex; } else { 494 if (delimiterIndex > 0) 499 return(reCheckRestOfTheCharacters(totalCharsSoFar-delimiterIndex, 500 delimiter, 501 delimiterLength)); 502 } 503 } else { 504 if (nextChar == fieldStopDelimiter[fieldStopDelimiterIndex]) { 506 fieldStopDelimiterIndex++; 507 if (fieldStopDelimiterIndex == fieldStopDelimiterLength) { 508 boolean skipped = skipDoubleDelimiters(fieldStopDelimiter); 509 if(!skipped) 510 { 511 foundStartDelimiter = false; 512 totalCharsSoFar = totalCharsSoFar - fieldStopDelimiterLength; 514 stopDelimiterPosition = totalCharsSoFar; 517 foundStartAndStopDelimiters = true; 519 }else 520 { 521 fieldStopDelimiterIndex =0 ; 522 } 523 return 0; 524 } 525 return 0; 526 } else { 527 if (fieldStopDelimiterIndex > 0) { 532 reCheckRestOfTheCharacters(totalCharsSoFar-fieldStopDelimiterIndex, 533 fieldStopDelimiter, fieldStopDelimiterLength); 534 return 0; 535 } 536 } 537 } 538 return 0; 539 } 540 541 private int reCheckRestOfTheCharacters(int startFrom, 545 char[] delimiter, int delimiterLength) { 546 int delimiterIndex = 0; 547 for (int i = startFrom; i<totalCharsSoFar; i++) { 551 if (currentToken[i] == delimiter[delimiterIndex]) 552 delimiterIndex++; 553 else 554 delimiterIndex = 0; 555 } 556 return delimiterIndex; 557 } 558 559 580 private boolean skipDoubleDelimiters(char [] characterDelimiter) throws IOException 581 { 582 boolean skipped = true; 583 int cDelLength = characterDelimiter.length ; 584 bufferedReader.mark(cDelLength); 585 for(int i = 0 ; i < cDelLength ; i++) 586 { 587 int nextChar = bufferedReader.read(); 588 if(nextChar != characterDelimiter[i]) 589 { 590 bufferedReader.reset(); 592 skipped = false; 593 break; 594 } 595 } 596 return skipped; 597 } 598 599 600 601 private void omitLineFeed() throws IOException 603 { 604 bufferedReader.mark(1); 605 int nextChar = bufferedReader.read(); 606 if(nextChar != '\n') 607 { 608 bufferedReader.reset(); 610 } 611 } 612 613 614 615 617 int getCurrentRowNumber() { 618 return lineNumber; 619 } 620 621 624 boolean readNextRow(String [] returnStringArray) throws Exception { 625 boolean readVal; 626 int idx; 627 628 if (!streamOpenForReading) { 629 openFile(); 630 if (hasColumnDefinition){ 633 ignoreFirstRow(); 634 } 635 } 636 if (formatCode == DEFAULT_FORMAT_CODE) 637 readVal=readNextDelimitedRow(returnStringArray); 638 else 639 readVal=readNextFixedRow(returnStringArray); 640 641 return readVal; 642 } 643 644 648 private boolean haveSep = true; 649 private boolean readNextFixedRow(String [] returnStringArray) throws Exception { 651 int readLength = 0; 653 int totalLength = 0; 654 655 while ((readLength += 657 bufferedReader.read(tempString, readLength, 658 rowWidth-readLength)) 659 < rowWidth) { 660 661 if (readLength == totalLength-1) { if ( readLength == -1) { return false; 664 } 665 else { 666 if (totalLength != rowWidth - recordSeparator.length) { 669 throw LoadError.unexpectedEndOfFile(lineNumber+1); 670 } 671 else { 672 haveSep = false; 673 break; 674 } 675 } 676 } 677 totalLength = readLength; 680 } 681 682 int colStart = 0; 683 for (int i=0; i< numberOfColumns; i++) { 684 int colWidth = columnWidths[i]; 685 686 if (colWidth == 0) returnStringArray[i] = null; 688 else { 689 String checkAgainstNullString = new String (tempString, colStart, colWidth); 691 if (checkAgainstNullString.trim().equals(nullString)) 692 returnStringArray[i] = null; 693 else 694 returnStringArray[i] = checkAgainstNullString; 695 colStart += colWidth; 696 } 697 } 698 699 if (haveSep) { 701 for (int i=(recordSeparatorLength-1); i>=0; i--) { 702 if (tempString[colStart+i] != recordSeparator[i]) 703 throw LoadError.recordSeparatorMissing(lineNumber+1); 704 } 705 } else haveSep = true; 707 lineNumber++; 708 return true; 709 } 710 711 private boolean readNextDelimitedRow(String [] returnStringArray) throws Exception { 715 716 int upperLimit = numberOfColumns-1; 718 if (upperLimit < 0) 720 return false; 721 722 for (int i = 0; i<upperLimit; i++) { 724 if (!readNextToken(fieldSeparator, 0, fieldSeparatorLength, false) ) { 725 if (i == 0) return false; 727 else 728 throw LoadError.unexpectedEndOfFile(lineNumber+1); 729 } 730 if (stopDelimiterPosition!=0 && ((stopDelimiterPosition) != totalCharsSoFar)) { 734 for (int k=stopDelimiterPosition+1; k<totalCharsSoFar; k++) { 735 if (Character.isWhitespace(currentToken[k])==false) { 746 throw LoadError.dataAfterStopDelimiter(lineNumber+1, i+1); 747 } 748 } 749 totalCharsSoFar = stopDelimiterPosition; 750 } 751 if (totalCharsSoFar != -1) { 753 returnStringArray[i] = new String (currentToken, 754 positionOfNonWhiteSpaceCharInFront, totalCharsSoFar); 755 } 756 else 757 returnStringArray[i] = null; 758 } 759 760 if (!readNextToken(recordSeparator, 0, recordSeparatorLength, true) ) { 766 if (upperLimit == 0) 767 return false; 768 else 769 throw LoadError.unexpectedEndOfFile(lineNumber+1); 770 } 771 if (stopDelimiterPosition!=0 && (stopDelimiterPosition != totalCharsSoFar)) { 775 for (int i=stopDelimiterPosition+1; i<totalCharsSoFar; i++) { 776 if (Character.isWhitespace(currentToken[i])==false) { 787 throw LoadError.dataAfterStopDelimiter(lineNumber+1, numberOfColumns); 788 } 789 } 790 totalCharsSoFar = stopDelimiterPosition; 791 } 792 793 if (hasDelimiterAtEnd) { 797 if (!(fieldStopDelimiterLength > 0)) { 800 804 --totalCharsSoFar; 807 } 809 } 810 811 if (totalCharsSoFar != -1) { 812 813 820 if (!hasDelimiterAtEnd) { returnStringArray[upperLimit] = new String (currentToken, 822 positionOfNonWhiteSpaceCharInFront, totalCharsSoFar); 823 } 824 else if (totalCharsSoFar==fieldSeparatorLength && isFieldSep(currentToken) ){ 825 827 String currentStr = new String (currentToken, 828 positionOfNonWhiteSpaceCharInFront, totalCharsSoFar); 829 830 if (currentToken[totalCharsSoFar+1]==fieldStopDelimiter[0]){ 831 returnStringArray[upperLimit] = currentStr; 832 } 833 else { 834 returnStringArray[upperLimit] = null; 835 } 836 } 837 else { 838 if (totalCharsSoFar>0) { 840 returnStringArray[upperLimit] = new String (currentToken, 841 positionOfNonWhiteSpaceCharInFront, totalCharsSoFar); 842 } 843 else{ 844 returnStringArray[upperLimit] = null; 845 } 846 } 847 } 848 else 849 returnStringArray[upperLimit] = null; 850 851 lineNumber++; 852 return true; 853 } 854 private boolean isFieldSep(char[] chrArray){ 856 for (int i=0; i<chrArray.length && i<fieldSeparatorLength; i++){ 857 if (chrArray[i]!=fieldSeparator[i]) 858 return false; 859 } 860 return true; 861 } 862 boolean readNextToken(char[] delimiter, int delimiterIndex, 864 int delimiterLength, 865 boolean isRecordSeperator) throws Exception { 866 int nextChar; 867 868 fieldStopDelimiterIndex = 0; 869 fieldStartDelimiterIndex = 0; 870 totalCharsSoFar = 0; 871 positionOfNonWhiteSpaceCharInFront = 0; 873 stopDelimiterPosition = 0; 874 foundStartAndStopDelimiters = false; 875 foundStartDelimiter = false; 876 int returnValue; 877 878 while (true) { 879 nextChar = bufferedReader.read(); 880 if (nextChar == -1) return false; 882 883 currentToken[totalCharsSoFar++] = (char)nextChar; 886 checkForWhiteSpaceInFront(); 888 if (totalCharsSoFar == currentTokenMaxSize) { 889 currentTokenMaxSize = currentTokenMaxSize * 2; 890 char[] tempArray = new char[currentTokenMaxSize]; 891 System.arraycopy(currentToken, 0, tempArray, 0, totalCharsSoFar); 892 currentToken = tempArray; 893 } 894 895 returnValue = lookForPassedSeparator(delimiter, delimiterIndex, 896 delimiterLength, nextChar, 897 isRecordSeperator); 898 if (returnValue == -1) { 899 if (!foundStartAndStopDelimiters ) { 902 if (totalCharsSoFar == 0) 903 totalCharsSoFar = -1; 904 else { 905 checkForWhiteSpaceInBack(); 909 totalCharsSoFar = totalCharsSoFar - positionOfNonWhiteSpaceCharInFront - positionOfNonWhiteSpaceCharInBack; 910 } 911 } 912 return true; 913 } 914 delimiterIndex = returnValue; 915 } 916 } 917 } 918 919 920 921 922 923 924 | Popular Tags |