1 21 22 package org.apache.derby.impl.store.raw.data; 23 24 import org.apache.derby.iapi.reference.SQLState; 25 26 import org.apache.derby.iapi.services.context.ContextService; 27 28 import org.apache.derby.iapi.services.sanity.SanityManager; 29 import org.apache.derby.iapi.services.io.Storable; 30 import org.apache.derby.iapi.services.io.StreamStorable; 31 import org.apache.derby.iapi.services.io.FormatIdInputStream; 32 import org.apache.derby.iapi.services.io.FormatIdOutputStream; 33 import org.apache.derby.iapi.services.io.FormatIdUtil; 34 import org.apache.derby.iapi.services.io.StoredFormatIds; 35 import org.apache.derby.iapi.services.io.TypedFormat; 36 import org.apache.derby.iapi.services.monitor.Monitor; 37 38 import org.apache.derby.iapi.error.StandardException; 39 import org.apache.derby.iapi.store.access.AccessFactory; 40 import org.apache.derby.iapi.store.access.RowSource; 41 import org.apache.derby.iapi.store.access.RowUtil; 42 import org.apache.derby.iapi.store.access.TransactionController; 43 import org.apache.derby.iapi.store.raw.ContainerKey; 44 import org.apache.derby.iapi.store.raw.RawStoreFactory; 45 import org.apache.derby.iapi.store.raw.StreamContainerHandle; 46 47 import org.apache.derby.io.StorageFactory; 48 import org.apache.derby.io.WritableStorageFactory; 49 import org.apache.derby.io.StorageFile; 50 51 import org.apache.derby.impl.store.raw.data.DecryptInputStream; 52 import org.apache.derby.impl.store.raw.data.StoredFieldHeader; 53 import org.apache.derby.impl.store.raw.data.StoredRecordHeader; 54 55 import org.apache.derby.iapi.services.io.ArrayInputStream; 56 import org.apache.derby.iapi.services.io.FormatableBitSet; 57 import org.apache.derby.iapi.services.io.CompressedNumber; 58 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream; 59 import org.apache.derby.iapi.services.io.LimitInputStream; 60 import org.apache.derby.iapi.services.property.PropertyUtil; 61 import org.apache.derby.iapi.util.ReuseFactory; 62 63 import java.util.Properties ; 64 import java.io.InputStream ; 65 import java.io.BufferedInputStream ; 66 import java.io.OutputStream ; 67 import java.io.IOException ; 68 import java.io.EOFException ; 69 import java.io.InvalidClassException ; 70 import java.io.Externalizable ; 71 import java.security.AccessController ; 72 import java.security.PrivilegedExceptionAction ; 73 import java.security.PrivilegedActionException ; 74 import java.io.FileNotFoundException ; 75 76 91 92 93 public class StreamFileContainer implements TypedFormat, PrivilegedExceptionAction 94 { 95 96 100 101 105 protected static int formatIdInteger = 106 StoredFormatIds.RAW_STORE_SINGLE_CONTAINER_STREAM_FILE; 107 108 109 protected static final int LARGE_SLOT_SIZE = 4; 111 112 protected static final int MIN_BUFFER_SIZE = 113 RawStoreFactory.STREAM_FILE_BUFFER_SIZE_MINIMUM; 114 protected static final int FIELD_STATUS = 115 StoredFieldHeader.setFixed(StoredFieldHeader.setInitial(), true); 116 protected static final int FIELD_HEADER_SIZE = 117 StoredFieldHeader.size(FIELD_STATUS, 0, LARGE_SLOT_SIZE); 118 119 120 124 protected ContainerKey identity; 125 private BaseDataFileFactory dataFactory; 127 private int bufferSize; 128 129 private StorageFile file; 130 131 private OutputStream fileOut; 132 private DynamicByteArrayOutputStream out; 133 private FormatIdOutputStream logicalDataOut; 134 135 private InputStream fileIn; 136 private BufferedInputStream bufferedIn; 137 private DecryptInputStream decryptIn; 138 private LimitInputStream limitIn; 139 private FormatIdInputStream logicalDataIn; 140 141 private StoredRecordHeader recordHeader; 142 143 private byte[] ciphertext; 144 private byte[] zeroBytes; 147 148 149 private static final int STORAGE_FILE_EXISTS_ACTION = 1; 150 private static final int STORAGE_FILE_DELETE_ACTION = 2; 151 private static final int STORAGE_FILE_MKDIRS_ACTION = 3; 152 private static final int STORAGE_FILE_GET_OUTPUT_STREAM_ACTION = 4; 153 private static final int STORAGE_FILE_GET_INPUT_STREAM_ACTION = 5; 154 private int actionCode; 155 private StorageFile actionStorageFile; 156 157 158 162 163 168 StreamFileContainer( 169 ContainerKey identity, 170 BaseDataFileFactory dataFactory) 171 throws StandardException 172 { 173 this.identity = identity; 174 this.dataFactory = dataFactory; 175 } 176 177 186 StreamFileContainer( 187 ContainerKey identity, 188 BaseDataFileFactory dataFactory, 189 Properties prop) 190 throws StandardException 191 { 192 this.identity = identity; 193 this.dataFactory = dataFactory; 194 195 try 196 { 197 file = getFileName(identity, true, false); 198 199 if (privExists(file)) 200 { 201 throw StandardException.newException( 204 SQLState.FILE_EXISTS, file); 205 } 206 207 getContainerProperties(prop); 210 211 } 212 catch (SecurityException se) 213 { 214 throw StandardException.newException( 215 SQLState.FILE_CREATE, se, file); 216 } 217 } 218 219 223 224 241 protected StreamFileContainer open(boolean forUpdate) 242 throws StandardException 243 { 244 245 file = getFileName(this.identity, false, true); 246 if (!privExists(file)) 247 return null; 248 249 try 250 { 251 if (!forUpdate) 252 { 253 fileIn = privGetInputStream(file); 254 255 if (dataFactory.databaseEncrypted()) 256 { 257 262 MemByteHolder byteHolder = 263 new MemByteHolder( 264 RawStoreFactory.STREAM_FILE_BUFFER_SIZE_DEFAULT); 265 266 decryptIn = 267 new DecryptInputStream(fileIn, byteHolder, dataFactory); 268 269 limitIn = new LimitInputStream(decryptIn); 270 } 271 else 272 { 273 bufferedIn = 274 new BufferedInputStream ( 275 fileIn, 276 RawStoreFactory.STREAM_FILE_BUFFER_SIZE_DEFAULT); 277 278 limitIn = new LimitInputStream(bufferedIn); 279 } 280 281 285 logicalDataIn = new FormatIdInputStream(limitIn); 286 287 recordHeader = new StoredRecordHeader(); 289 recordHeader.read(logicalDataIn); 290 291 } 292 else 293 { 294 if (SanityManager.DEBUG) 295 SanityManager.THROWASSERT( 296 "updating existing stream container not supported yet"); 297 298 return null; 299 } 300 } 301 catch (IOException ioe) 302 { 303 throw StandardException.newException( 304 SQLState.FILE_CREATE, ioe, file); 305 } 306 307 return this; 308 } 309 310 318 protected void close() 319 { 320 try 321 { 322 323 if (fileIn != null) 324 { 325 fileIn.close(); 326 fileIn = null; 327 if (dataFactory.databaseEncrypted()) 328 { 329 decryptIn.close(); 330 decryptIn = null; 331 } 332 else 333 { 334 bufferedIn.close(); 335 bufferedIn = null; 336 } 337 logicalDataIn.close(); 338 logicalDataIn = null; 339 } 340 341 if (fileOut != null) 342 { 343 fileOut.close(); 344 logicalDataOut.close(); 345 fileOut = null; 346 logicalDataOut = null; 347 out = null; 348 } 349 350 } 351 catch (IOException ioe) 352 { 353 357 361 } 362 } 363 364 368 369 372 public int getTypeFormatId() 373 { 374 return StoredFormatIds.RAW_STORE_SINGLE_CONTAINER_STREAM_FILE; 375 } 376 377 404 public void getContainerProperties(Properties prop) 405 throws StandardException 406 { 407 408 AccessFactory af = (AccessFactory) 409 Monitor.getServiceModule(dataFactory, AccessFactory.MODULE); 410 411 TransactionController tc = 412 (af == null) ? 413 null : 414 af.getTransaction( 415 ContextService.getFactory().getCurrentContextManager()); 416 417 bufferSize = 418 PropertyUtil.getServiceInt(tc, prop, 419 RawStoreFactory.STREAM_FILE_BUFFER_SIZE_PARAMETER, 420 RawStoreFactory.STREAM_FILE_BUFFER_SIZE_MINIMUM, 421 RawStoreFactory.STREAM_FILE_BUFFER_SIZE_MAXIMUM, 422 RawStoreFactory.STREAM_FILE_BUFFER_SIZE_DEFAULT); 423 } 424 425 428 public ContainerKey getIdentity() 429 { 430 return this.identity; 431 } 432 433 442 protected boolean use(StreamContainerHandle handle) 443 throws StandardException 444 { 445 return true; 446 } 447 448 458 public void load(RowSource rowSource) 459 throws StandardException 460 { 461 out = new DynamicByteArrayOutputStream(bufferSize); 463 logicalDataOut = new FormatIdOutputStream(out); 464 boolean encrypted = dataFactory.databaseEncrypted(); 465 466 if (encrypted) 470 { 471 if (zeroBytes == null) 472 zeroBytes = new byte[dataFactory.getEncryptionBlockSize() - 1]; 473 474 out.write(zeroBytes, 0, dataFactory.getEncryptionBlockSize() - 1); 475 } 476 477 try 478 { 479 fileOut = privGetOutputStream(file); 480 481 FormatableBitSet validColumns = rowSource.getValidColumns(); 482 483 Object [] row = rowSource.getNextRowFromRowSource(); 484 485 int numberFields = 0; 486 if (validColumns != null) 487 { 488 for (int i = validColumns.getLength() - 1; i >= 0; i--) 489 { 490 if (validColumns.isSet(i)) 491 { 492 numberFields = i + 1; 493 break; 494 } 495 } 496 } 497 else 498 { 499 numberFields = row.length; 500 } 501 502 recordHeader = new StoredRecordHeader(0, numberFields); 504 505 int rhLen = recordHeader.write(out); 508 509 int validColumnsSize = 510 validColumns == null ? 0 : validColumns.getLength(); 511 512 while (row != null) 513 { 514 515 int arrayPosition = -1; 516 517 for (int i = 0; i < numberFields; i++) 518 { 519 520 if (validColumns == null) 522 { 523 arrayPosition++; 524 Object column = row[arrayPosition]; 525 writeColumn(column); 526 } 527 else 528 { 529 530 if (validColumnsSize > i && validColumns.isSet(i)) 531 { 532 arrayPosition++; 533 Object column = row[arrayPosition]; 534 writeColumn(column); 535 } 536 else 537 { 538 writeColumn(null); 540 } 541 } 542 543 if ((out.getUsed() >= bufferSize) || 547 ((bufferSize - out.getUsed()) < MIN_BUFFER_SIZE)) 548 { 549 writeToFile(); 550 } 551 } 552 553 row = rowSource.getNextRowFromRowSource(); 555 } 556 557 558 if (encrypted) 562 { 563 if (out.getUsed() > (dataFactory.getEncryptionBlockSize() - 1)) 564 writeToFile(); 565 } 566 else if (out.getUsed() > 0) 567 { 568 writeToFile(); 569 } 570 571 } 572 catch (IOException ioe) 573 { 574 throw StandardException.newException( 576 SQLState.DATA_UNEXPECTED_EXCEPTION, ioe); 577 578 } 579 finally 580 { 581 close(); 582 } 583 } 584 585 588 602 private void writeToFile() 603 throws StandardException 604 { 605 606 try 607 { 608 if (dataFactory.databaseEncrypted()) 609 { 610 int realLen = out.getUsed() - (dataFactory.getEncryptionBlockSize() - 1); 614 int tail = realLen % dataFactory.getEncryptionBlockSize(); 615 int padding = 616 (tail == 0) ? 0 : 617 (dataFactory.getEncryptionBlockSize() - tail); 618 619 int startByte = (tail == 0) ? (dataFactory.getEncryptionBlockSize() - 1) : (tail - 1); 620 int encryptedLen = realLen + padding; 621 622 if (realLen <= 0) 624 return; 625 626 if (ciphertext == null) 627 { 628 ciphertext = new byte[encryptedLen]; 629 } 630 else 631 { 632 if (ciphertext.length < encryptedLen) 633 ciphertext = new byte[encryptedLen]; 634 } 635 636 dataFactory.encrypt( 637 out.getByteArray(), startByte, encryptedLen, ciphertext, 0, false); 638 639 CompressedNumber.writeInt(fileOut, realLen); 641 dataFactory.writeInProgress(); 642 try 643 { 644 fileOut.write(ciphertext, 0, encryptedLen); 645 } 646 finally 647 { 648 dataFactory.writeFinished(); 649 } 650 651 out.reset(); 653 654 if (dataFactory.databaseEncrypted()) 656 { 657 if (zeroBytes == null) 658 zeroBytes = new byte[dataFactory.getEncryptionBlockSize() - 1]; 659 660 out.write(zeroBytes, 0, dataFactory.getEncryptionBlockSize() - 1); 661 } 662 663 } 664 else 665 { 666 if (out.getUsed() == 0) 668 return; 669 670 dataFactory.writeInProgress(); 671 try 672 { 673 fileOut.write(out.getByteArray(), 0, out.getUsed()); 674 } 675 finally 676 { 677 dataFactory.writeFinished(); 678 } 679 680 out.reset(); 682 } 683 } 684 catch (IOException ioe) 685 { 686 throw StandardException.newException( 687 SQLState.DATA_UNEXPECTED_EXCEPTION, ioe); 688 } 689 } 690 691 private void writeColumn(Object column) 692 throws StandardException, IOException 693 { 694 695 int fieldStatus = FIELD_STATUS; 696 if (column == null) 697 { 698 fieldStatus = StoredFieldHeader.setNonexistent(fieldStatus); 700 StoredFieldHeader.write(out, fieldStatus, 0, LARGE_SLOT_SIZE); 701 return; 702 } 703 704 if (column instanceof Storable) 706 { 707 Storable sColumn = (Storable) column; 708 if (sColumn.isNull()) 709 { 710 fieldStatus = StoredFieldHeader.setNull(fieldStatus, true); 711 StoredFieldHeader.write(out, fieldStatus, 0, LARGE_SLOT_SIZE); 712 return; 713 } 714 } 715 716 int beginPosition = out.getPosition(); 717 int fieldDataLength = 0; 718 719 StoredFieldHeader.write( 721 out, fieldStatus, fieldDataLength, LARGE_SLOT_SIZE); 722 723 if (column instanceof StreamStorable) 724 { 725 if (((StreamStorable) column).returnStream() != null) 726 { 727 column = (InputStream) ((StreamStorable) column).returnStream(); 728 } 729 } 730 731 if (column instanceof InputStream) 732 { 733 InputStream inColumn = (InputStream) column; 734 int bufferLen = inColumn.available(); 735 byte[] bufData = new byte[bufferLen]; 736 737 do 738 { 739 int lenRead = inColumn.read(bufData, bufferLen, 0); 740 if (lenRead != -1) 741 { 742 fieldDataLength += lenRead; 743 out.write(bufData, lenRead, 0); 744 } 745 else 746 { 747 break; 748 } 749 } while (true); 750 751 } 752 else if (column instanceof Storable) 753 { 754 755 Storable sColumn = (Storable) column; 756 758 sColumn.writeExternal(logicalDataOut); 759 fieldDataLength = 760 out.getPosition() - beginPosition - FIELD_HEADER_SIZE; 761 762 } 763 else 764 { 765 logicalDataOut.writeObject(column); 768 fieldDataLength = 769 out.getPosition() - beginPosition - FIELD_HEADER_SIZE; 770 } 771 772 int endPosition = out.getPosition(); 774 out.setPosition(beginPosition); 775 776 StoredFieldHeader.write( 777 out, fieldStatus, fieldDataLength, LARGE_SLOT_SIZE); 778 779 if (!StoredFieldHeader.isNull(fieldStatus)) 781 out.setPosition(endPosition); 782 } 783 784 public boolean fetchNext(Object [] row) 785 throws StandardException 786 { 787 788 boolean inUserCode = false; 789 int columnId = 0; 790 791 try 792 { 793 794 int numberFields = recordHeader.getNumberFields(); 796 797 int arrayPosition = 0; 798 for (columnId = 0; columnId < numberFields; columnId++) 799 { 800 801 if (arrayPosition >= row.length) 802 break; 803 804 limitIn.clearLimit(); 805 806 int fieldStatus = StoredFieldHeader.readStatus(logicalDataIn); 808 int fieldDataLength = StoredFieldHeader.readFieldDataLength( 809 logicalDataIn, fieldStatus, LARGE_SLOT_SIZE); 810 811 limitIn.setLimit(fieldDataLength); 812 813 if (SanityManager.DEBUG) 814 { 815 816 if (StoredFieldHeader.isExtensible(fieldStatus)) 817 { 818 SanityManager.THROWASSERT( 819 "extensible fields not supported yet. columnId = " 820 + columnId); 821 } 822 823 SanityManager.ASSERT(!StoredFieldHeader.isOverflow(fieldStatus), 824 "overflow field is not supported yet"); 825 } 826 827 Object column = row[arrayPosition]; 828 829 if (StoredFieldHeader.isNullable(fieldStatus)) 831 { 832 833 if (column == null) 834 { 835 throw StandardException.newException( 836 SQLState.DATA_NULL_STORABLE_COLUMN, 837 Integer.toString(columnId)); 838 } 839 840 if (!(column instanceof Storable)) 842 { 843 throw StandardException.newException( 844 SQLState.DATA_NULL_STORABLE_COLUMN, 845 column.getClass().getName()); 846 } 847 848 Storable sColumn = (Storable) column; 849 850 if (StoredFieldHeader.isNull(fieldStatus)) 852 { 853 854 sColumn.restoreToNull(); 855 arrayPosition++; 856 continue; 857 } 858 859 inUserCode = true; 860 sColumn.readExternal(logicalDataIn); 861 inUserCode = false; 862 arrayPosition++; 863 continue; 864 } 865 866 if (StoredFieldHeader.isNull(fieldStatus)) 868 { 869 throw StandardException.newException( 870 SQLState.DATA_NULL_STORABLE_COLUMN, 871 Integer.toString(columnId)); 872 } 873 874 880 Object neColumn = row[arrayPosition]; 881 882 if (neColumn instanceof Externalizable ) 883 { 884 885 Externalizable exColumn = (Externalizable ) neColumn; 886 887 inUserCode = true; 888 exColumn.readExternal(logicalDataIn); 889 inUserCode = false; 890 891 arrayPosition++; 892 continue; 893 } 894 895 neColumn = null; 897 inUserCode = true; 898 row[arrayPosition] = logicalDataIn.readObject(); 899 inUserCode = false; 900 901 arrayPosition++; 902 continue; 903 } 904 905 } 906 catch (IOException ioe) 907 { 908 909 if (inUserCode) 912 { 913 914 if (ioe instanceof EOFException ) 915 { 916 throw StandardException.newException( 917 SQLState.DATA_STORABLE_READ_MISMATCH, 918 ioe, logicalDataIn.getErrorInfo()); 919 } 920 921 throw StandardException.newException( 922 SQLState.DATA_STORABLE_READ_EXCEPTION, 923 ioe, logicalDataIn.getErrorInfo()); 924 } 925 926 if (ioe instanceof InvalidClassException ) 927 { 928 throw StandardException.newException( 929 SQLState.DATA_STORABLE_READ_EXCEPTION, 930 ioe, logicalDataIn.getErrorInfo()); 931 } 932 933 if ((ioe instanceof EOFException ) && (columnId == 0)) 936 { 937 close(); 938 return false; 939 } 940 941 throw dataFactory.markCorrupt( 942 StandardException.newException( 943 SQLState.DATA_CORRUPT_STREAM_CONTAINER, ioe, identity)); 944 945 } 946 catch (ClassNotFoundException cnfe) 947 { 948 949 if (SanityManager.DEBUG) 950 { 951 SanityManager.ASSERT(inUserCode); 952 } 953 954 throw StandardException.newException( 957 SQLState.DATA_STORABLE_READ_MISSING_CLASS, cnfe, 958 logicalDataIn.getErrorInfo()); 959 960 } 961 catch (LinkageError le) 962 { 963 if (inUserCode) 964 { 965 throw StandardException.newException( 966 SQLState.DATA_STORABLE_READ_EXCEPTION, le, 967 logicalDataIn.getErrorInfo()); 968 } 969 throw le; 970 } 971 972 return true; 973 974 } 975 976 981 public boolean removeContainer() 982 throws StandardException 983 { 984 close(); 985 986 if (privExists(file)) 987 { 988 return privDelete(file); 989 } 990 else 991 { 992 return true; 993 } 994 995 996 } 997 998 1006 protected StorageFile getFileName( 1007 ContainerKey identity, 1008 boolean forCreate, 1009 boolean errorOK) 1010 throws StandardException 1011 { 1012 if (identity.getSegmentId() == StreamContainerHandle.TEMPORARY_SEGMENT) 1013 { 1014 return( dataFactory.storageFactory.newStorageFile( dataFactory.storageFactory.getTempDir(), 1015 "T" + identity.getContainerId() + ".tmp")); 1016 } 1017 else 1018 { 1019 if (SanityManager.DEBUG) 1020 SanityManager.THROWASSERT( 1021 "cannot create stream container in non-temp segments yet."); 1022 1023 StorageFile container = dataFactory.getContainerPath( identity, false); 1024 1025 if (!privExists(container)) 1026 { 1027 1028 if (!forCreate) 1029 return null; 1030 1031 StorageFile directory = container.getParentDir(); 1032 1033 if (!privExists(directory)) 1034 { 1035 synchronized(dataFactory) 1037 { 1038 if (!privExists(directory)) 1039 { 1040 if (!privMkdirs(directory)) 1041 { 1042 if (errorOK) 1043 return null; 1044 else 1045 throw StandardException.newException( 1046 SQLState.FILE_CANNOT_CREATE_SEGMENT, 1047 directory); 1048 } 1049 } 1050 } 1051 } 1052 } 1053 return container; 1054 } 1055 } 1056 1057 1058 1059 1060 private synchronized boolean privExists(StorageFile file) 1061 { 1062 actionCode = STORAGE_FILE_EXISTS_ACTION; 1063 actionStorageFile = file; 1064 1065 try 1066 { 1067 Object ret = AccessController.doPrivileged( this); 1068 return ((Boolean ) ret).booleanValue(); 1069 }catch( PrivilegedActionException pae) 1070 { 1071 return false; 1074 } 1075 finally 1076 { 1077 actionStorageFile = null; 1078 } 1079 } 1080 1081 private synchronized boolean privMkdirs(StorageFile file) 1082 { 1083 actionCode = STORAGE_FILE_MKDIRS_ACTION; 1084 actionStorageFile = file; 1085 1086 try 1087 { 1088 Object ret = AccessController.doPrivileged( this); 1089 return ((Boolean ) ret).booleanValue(); 1090 }catch( PrivilegedActionException pae) 1091 { 1092 return false; 1095 } 1096 finally 1097 { 1098 actionStorageFile = null; 1099 } 1100 } 1101 1102 1103 private synchronized boolean privDelete(StorageFile file) 1104 { 1105 actionCode = STORAGE_FILE_DELETE_ACTION; 1106 actionStorageFile = file; 1107 1108 try 1109 { 1110 Object ret = AccessController.doPrivileged( this); 1111 return ((Boolean ) ret).booleanValue(); 1112 }catch( PrivilegedActionException pae) 1113 { 1114 return false; 1117 } 1118 finally 1119 { 1120 actionStorageFile = null; 1121 } 1122 } 1123 1124 private synchronized OutputStream privGetOutputStream(StorageFile file) 1125 throws FileNotFoundException 1126 { 1127 actionCode = STORAGE_FILE_GET_OUTPUT_STREAM_ACTION; 1128 actionStorageFile = file; 1129 1130 try 1131 { 1132 return (OutputStream) AccessController.doPrivileged( this); 1133 }catch( PrivilegedActionException pae) 1134 { 1135 throw (FileNotFoundException )pae.getException(); 1136 } 1137 finally 1138 { 1139 actionStorageFile = null; 1140 } 1141 } 1142 1143 1144 private synchronized InputStream privGetInputStream(StorageFile file) 1145 throws FileNotFoundException 1146 { 1147 actionCode = STORAGE_FILE_GET_INPUT_STREAM_ACTION; 1148 actionStorageFile = file; 1149 1150 try 1151 { 1152 return (InputStream) AccessController.doPrivileged( this); 1153 }catch( PrivilegedActionException pae) 1154 { 1155 throw (FileNotFoundException )pae.getException(); 1156 } 1157 finally 1158 { 1159 actionStorageFile = null; 1160 } 1161 } 1162 1163 1164 public Object run() throws FileNotFoundException 1166 { 1167 switch(actionCode) 1168 { 1169 case STORAGE_FILE_EXISTS_ACTION: 1170 return ReuseFactory.getBoolean(actionStorageFile.exists()); 1171 case STORAGE_FILE_DELETE_ACTION: 1172 return ReuseFactory.getBoolean(actionStorageFile.delete()); 1173 case STORAGE_FILE_MKDIRS_ACTION: 1174 return ReuseFactory.getBoolean(actionStorageFile.mkdirs()); 1175 case STORAGE_FILE_GET_OUTPUT_STREAM_ACTION: 1176 return actionStorageFile.getOutputStream(); 1177 case STORAGE_FILE_GET_INPUT_STREAM_ACTION: 1178 return actionStorageFile.getInputStream(); 1179 } 1180 1181 return null; 1182 } 1183 1184} 1185 | Popular Tags |