1 21 22 package org.apache.derby.impl.services.monitor; 23 24 import org.apache.derby.iapi.reference.MessageId; 25 import org.apache.derby.iapi.reference.SQLState; 26 27 import org.apache.derby.iapi.services.i18n.MessageService; 28 29 import org.apache.derby.iapi.services.monitor.Monitor; 30 import org.apache.derby.iapi.services.monitor.PersistentService; 31 import org.apache.derby.iapi.services.sanity.SanityManager; 32 33 import org.apache.derby.iapi.error.StandardException; 34 import org.apache.derby.iapi.store.raw.data.DataFactory; 35 36 import org.apache.derby.io.StorageFile; 37 import org.apache.derby.io.StorageFactory; 38 import org.apache.derby.io.WritableStorageFactory; 39 40 import org.apache.derby.iapi.reference.Attribute; 41 import org.apache.derby.iapi.reference.Property; 42 43 import java.io.File ; 44 import java.io.FileInputStream ; 45 import java.io.FileOutputStream ; 46 import java.io.InputStream ; 47 import java.io.BufferedInputStream ; 48 import java.io.OutputStream ; 49 import java.io.IOException ; 50 import java.io.FileNotFoundException ; 51 52 import java.util.Enumeration ; 53 import java.util.NoSuchElementException ; 54 import java.util.Properties ; 55 56 import java.security.AccessController ; 57 import java.security.PrivilegedAction ; 58 import java.security.PrivilegedExceptionAction ; 59 import java.security.PrivilegedActionException ; 60 61 65 final class StorageFactoryService implements PersistentService 66 { 67 68 private String home; private String canonicalHome; private final String subSubProtocol; 71 private final Class storageFactoryClass; 72 private StorageFactory rootStorageFactory; 73 private char separatorChar; 74 75 StorageFactoryService( String subSubProtocol, Class storageFactoryClass) 76 throws StandardException 77 { 78 this.subSubProtocol = subSubProtocol; 79 this.storageFactoryClass = storageFactoryClass; 80 81 Object monitorEnv = Monitor.getMonitor().getEnvironment(); 82 if (monitorEnv instanceof File) 83 { 84 final File relativeRoot = (File) monitorEnv; 85 try 86 { 87 AccessController.doPrivileged( 88 new java.security.PrivilegedExceptionAction () 89 { 90 public Object run() throws IOException , StandardException 91 { 92 home = relativeRoot.getPath(); 93 canonicalHome = relativeRoot.getCanonicalPath(); 94 rootStorageFactory = getStorageFactoryInstance( true, null, null, null); 95 if( home != null) 96 { 97 StorageFile rootDir = rootStorageFactory.newStorageFile( null); 98 rootDir.mkdirs(); 99 } 100 return null; 101 } 102 } 103 ); 104 } 105 catch( PrivilegedActionException pae) 106 { 107 home = null; 108 canonicalHome = null; 109 } 110 } 111 if( rootStorageFactory == null) 112 { 113 try 114 { 115 rootStorageFactory = getStorageFactoryInstance( true, null, null, null); 116 } 117 catch( IOException ioe){ throw Monitor.exceptionStartingModule( ioe); } 118 } 119 AccessController.doPrivileged( 120 new java.security.PrivilegedAction () 121 { 122 public Object run() 123 { 124 separatorChar = rootStorageFactory.getSeparator(); 125 return null; 126 } 127 } 128 ); 129 } 131 132 135 136 139 public boolean hasStorageFactory() 140 { 141 return true; 142 } 143 144 163 public StorageFactory getStorageFactoryInstance(final boolean useHome, 164 final String databaseName, 165 final String tempDirName, 166 final String uniqueName) 167 throws StandardException, IOException 168 { 169 try 170 { 171 return (StorageFactory) AccessController.doPrivileged( 172 new PrivilegedExceptionAction () 173 { 174 public Object run() throws InstantiationException , IllegalAccessException , IOException 175 { 176 return privGetStorageFactoryInstance( useHome, databaseName, tempDirName, uniqueName); 177 } 178 }); 179 } 180 catch (PrivilegedActionException pae) 181 { 182 Exception e = pae.getException(); 183 throw StandardException.newException( SQLState.REGISTERED_CLASS_INSTANCE_ERROR, 184 e, subSubProtocol, storageFactoryClass); 185 } 186 } 188 private StorageFactory privGetStorageFactoryInstance( boolean useHome, 189 String databaseName, 190 String tempDirName, 191 String uniqueName) 192 throws InstantiationException , IllegalAccessException , IOException 193 { 194 StorageFactory storageFactory = (StorageFactory) storageFactoryClass.newInstance(); 195 String dbn; 196 if( databaseName != null 197 && subSubProtocol != null 198 && databaseName.startsWith( subSubProtocol + ":")) 199 dbn = databaseName.substring( subSubProtocol.length() + 1); 200 else 201 dbn = databaseName; 202 storageFactory.init( useHome ? home : null, dbn, tempDirName, uniqueName); 203 return storageFactory; 204 } 206 211 public String getType() 212 { 213 return subSubProtocol; 214 } 215 216 217 222 public Enumeration getBootTimeServices() 223 { 224 if( home == null) 225 return null; 226 return new DirectoryList(); 227 } 228 229 239 public Properties getServiceProperties( final String serviceName, Properties defaultProperties) 240 throws StandardException 241 { 242 if (SanityManager.DEBUG) { 243 if (! serviceName.equals(getCanonicalServiceName(serviceName))) 244 { 245 SanityManager.THROWASSERT("serviceName (" + serviceName + 246 ") expected to equal getCanonicalServiceName(serviceName) (" + 247 getCanonicalServiceName(serviceName) + ")"); 248 } 249 } 250 251 final String recreateFrom = recreateServiceRoot(serviceName, defaultProperties); 253 254 InputStream is = null; 255 try 256 { 257 is = (InputStream ) AccessController.doPrivileged( 258 new PrivilegedExceptionAction () 259 { 260 public Object run() 261 throws FileNotFoundException , IOException , StandardException, 262 InstantiationException , IllegalAccessException 263 { 264 if( recreateFrom != null) { 266 File propFile = new File(recreateFrom, PersistentService.PROPERTIES_NAME); 267 return new FileInputStream (propFile); 268 } 269 else 270 { 271 StorageFactory storageFactory = privGetStorageFactoryInstance( true, serviceName, null, null); 272 StorageFile file = storageFactory.newStorageFile( PersistentService.PROPERTIES_NAME); 273 InputStream is1 = file.getInputStream(); 274 storageFactory.shutdown(); 275 return is1; 276 } 277 } 278 } 279 ); 280 281 Properties serviceProperties = new Properties (defaultProperties); 282 serviceProperties.load(new BufferedInputStream (is)); 283 284 return serviceProperties; 285 } 286 catch (PrivilegedActionException pae) 287 { 288 if( pae.getException() instanceof FileNotFoundException ) 289 return null; 290 throw Monitor.exceptionStartingModule( pae.getException()); 291 } 292 catch (FileNotFoundException fnfe) {return null ;} 293 catch (SecurityException se) { throw Monitor.exceptionStartingModule( se); } 294 catch (IOException ioe) { throw Monitor.exceptionStartingModule( ioe); } 295 finally 296 { 297 if (is != null) 298 { 299 try 300 { 301 is.close(); 302 } 303 catch (IOException ioe2) {} 304 } 305 } 306 } 308 309 312 313 public void saveServiceProperties( final String serviceName, 314 StorageFactory sf, 315 final Properties properties, 316 final boolean replace) 317 throws StandardException 318 { 319 if (SanityManager.DEBUG) 320 { 321 SanityManager.ASSERT(serviceName.equals(getCanonicalServiceName(serviceName)), serviceName); 322 } 323 if( ! (sf instanceof WritableStorageFactory)) 324 throw StandardException.newException(SQLState.READ_ONLY_SERVICE); 325 final WritableStorageFactory storageFactory = (WritableStorageFactory) sf; 326 try 327 { 328 AccessController.doPrivileged( 329 new PrivilegedExceptionAction () 330 { 331 public Object run() throws StandardException 332 { 333 StorageFile backupFile = null; 334 StorageFile servicePropertiesFile = storageFactory.newStorageFile( PersistentService.PROPERTIES_NAME); 335 336 if (replace) 337 { 338 backupFile = storageFactory.newStorageFile( PersistentService.PROPERTIES_NAME.concat("old")); 339 try 340 { 341 if(!servicePropertiesFile.renameTo(backupFile)) 342 throw StandardException.newException(SQLState.UNABLE_TO_RENAME_FILE, 343 servicePropertiesFile, backupFile); 344 } 345 catch (SecurityException se) { throw Monitor.exceptionStartingModule(se); } 346 } 347 348 OutputStream os = null; 349 try 350 { 351 os = servicePropertiesFile.getOutputStream(); 352 properties.store( os, serviceName + MessageService.getTextMessage(MessageId.SERVICE_PROPERTIES_DONT_EDIT)); 353 storageFactory.sync( os, false); 354 os.close(); 355 os = null; 356 } 357 catch (IOException ioe) 358 { 359 if (os != null) 360 { 361 try 362 { 363 os.close(); 364 } 365 catch (IOException ioe2) {} 366 os = null; 367 } 368 369 if (backupFile != null) 370 { 371 try 373 { 374 servicePropertiesFile.delete(); 375 backupFile.renameTo(servicePropertiesFile); 376 } 377 catch (SecurityException se) {} 378 } 379 throw Monitor.exceptionStartingModule(ioe); 380 } 381 382 if (backupFile != null) 383 { 384 try 385 { 386 backupFile.delete(); 387 backupFile = null; 388 } 389 catch (SecurityException se) {} 390 } 391 return null; 392 } 393 } 394 ); 395 } 396 catch( PrivilegedActionException pae) { throw (StandardException) pae.getException();} 397 } 399 404 405 public void saveServiceProperties(final String serviceName, 406 final Properties properties, 407 final boolean replace) 408 throws StandardException { 409 410 try 411 { 412 AccessController.doPrivileged( 413 new PrivilegedExceptionAction () 414 { 415 File backupFile = null; 416 public Object run() throws StandardException 417 { 418 419 File servicePropertiesFile = 420 new File(serviceName, PersistentService.PROPERTIES_NAME); 421 if (replace) { 422 backupFile = 423 new File(serviceName, PersistentService.PROPERTIES_NAME.concat("old")); 424 try { 425 if(!servicePropertiesFile.renameTo(backupFile)) { 426 throw StandardException.newException( 427 SQLState.UNABLE_TO_RENAME_FILE, servicePropertiesFile, backupFile); 428 } 429 } catch (SecurityException se) { 430 throw Monitor.exceptionStartingModule(se); 431 } 432 } 433 434 FileOutputStream fos = null; 435 try { 436 437 fos = new FileOutputStream (servicePropertiesFile); 438 properties.store(fos, 439 serviceName + 440 MessageService.getTextMessage( 441 MessageId.SERVICE_PROPERTIES_DONT_EDIT)); 442 fos.getFD().sync(); 443 fos.close(); 444 fos = null; 445 } catch (IOException ioe) { 446 447 if (fos != null) { 448 try { 449 fos.close(); 450 } catch (IOException ioe2) { 451 } 452 fos = null; 453 } 454 455 if (backupFile != null) { 456 try { 458 servicePropertiesFile.delete(); 459 backupFile.renameTo(servicePropertiesFile); 460 } catch (SecurityException se) { 461 } 462 } 463 throw Monitor.exceptionStartingModule(ioe); 464 } 465 466 467 if (backupFile != null) { 468 try { 469 backupFile.delete(); 470 backupFile = null; 471 } catch (SecurityException se) { 472 } 474 } 475 return null; 476 } 477 } 478 ); 479 }catch( PrivilegedActionException pae) { throw (StandardException) pae.getException();} 480 } 481 482 501 502 protected String recreateServiceRoot( final String serviceName, 503 Properties properties) throws StandardException 504 { 505 if(properties == null) { 507 return null; 508 } 509 510 String restoreFrom; boolean createRoot = false; 512 boolean deleteExistingRoot = false; 513 514 restoreFrom = properties.getProperty(Attribute.CREATE_FROM); 516 if(restoreFrom !=null) 517 { 518 createRoot =true; 520 deleteExistingRoot = false; 521 } 522 else 523 { restoreFrom = properties.getProperty(Attribute.RESTORE_FROM); 525 if(restoreFrom !=null) 527 { 528 createRoot =true; 529 deleteExistingRoot = true; 530 } 531 else 532 { 533 restoreFrom = properties.getProperty(Attribute.ROLL_FORWARD_RECOVERY_FROM); 535 if(restoreFrom !=null) 536 { 537 try 542 { 543 if( AccessController.doPrivileged( 544 new PrivilegedExceptionAction () 545 { 546 public Object run() 547 throws IOException , StandardException, InstantiationException , IllegalAccessException 548 { 549 StorageFactory storageFactory 550 = privGetStorageFactoryInstance( true, serviceName, null, null); 551 try 552 { 553 StorageFile serviceDirectory = storageFactory.newStorageFile( null); 554 return serviceDirectory.exists() ? this : null; 555 } 556 finally {storageFactory.shutdown();} 557 } 558 } 559 ) == null) 560 { 561 createRoot =true; 562 deleteExistingRoot = false; 563 } 564 565 } 566 catch( PrivilegedActionException pae) 567 { 568 throw Monitor.exceptionStartingModule( (IOException ) pae.getException()); 569 } 570 } 571 } 572 } 573 574 if(restoreFrom != null) 576 { 577 File backupRoot = new File(restoreFrom); 579 if(backupRoot.exists()) 580 { 581 File bserviceProp = new File(restoreFrom, PersistentService.PROPERTIES_NAME); 583 if(bserviceProp.exists()) 584 { 585 if(createRoot) 587 createServiceRoot(serviceName, deleteExistingRoot); 588 try 589 { 590 AccessController.doPrivileged( 591 new PrivilegedExceptionAction () 592 { 593 public Object run() 594 throws IOException , StandardException, InstantiationException , IllegalAccessException 595 { 596 WritableStorageFactory storageFactory = 597 (WritableStorageFactory) privGetStorageFactoryInstance( true, 598 serviceName, 599 null, 600 null); 601 try 602 { 603 StorageFile cserviceProp = storageFactory.newStorageFile( PersistentService.PROPERTIES_NAME); 604 605 if(cserviceProp.exists()) 606 if(!cserviceProp.delete()) 607 throw StandardException.newException(SQLState.UNABLE_TO_DELETE_FILE, 608 cserviceProp); 609 return null; 610 } 611 finally { storageFactory.shutdown();} 612 } 613 } 614 ); 615 } 616 catch( PrivilegedActionException pae) 617 { throw Monitor.exceptionStartingModule( (IOException )pae.getException());} 618 } 619 else 620 throw StandardException.newException(SQLState.PROPERTY_FILE_NOT_FOUND_IN_BACKUP, bserviceProp); 621 } 622 else 623 throw StandardException.newException(SQLState.SERVICE_DIRECTORY_NOT_IN_BACKUP, backupRoot); 624 625 properties.put(Property.IN_RESTORE_FROM_BACKUP,"True"); 626 if(createRoot) 627 properties.put(Property.DELETE_ROOT_ON_ERROR, "True"); 628 } 629 return restoreFrom; 630 } 632 635 public String createServiceRoot(final String name, final boolean deleteExisting) 636 throws StandardException 637 { 638 if( !( rootStorageFactory instanceof WritableStorageFactory)) 639 throw StandardException.newException(SQLState.READ_ONLY_SERVICE); 640 644 Throwable t = null; 645 try 646 { 647 String protocolLeadIn = ""; 648 652 if (!(getType().equals( PersistentService.DIRECTORY))) 653 protocolLeadIn = getType() + ":"; 654 655 return protocolLeadIn + (String ) AccessController.doPrivileged( 656 new PrivilegedExceptionAction () 657 { 658 public Object run() 659 throws StandardException, IOException , InstantiationException , IllegalAccessException 660 { 661 StorageFactory storageFactory = privGetStorageFactoryInstance( true, name, null, null); 662 try 663 { 664 StorageFile serviceDirectory = storageFactory.newStorageFile( null); 665 666 if (serviceDirectory.exists()) 667 { 668 if (deleteExisting) 669 { 670 if (!serviceDirectory.deleteAll()) 671 throw StandardException.newException(SQLState.SERVICE_DIRECTORY_REMOVE_ERROR, 672 getDirectoryPath( name)); 673 } 674 else 675 throw StandardException.newException(SQLState.SERVICE_DIRECTORY_EXISTS_ERROR, 676 getDirectoryPath( name)); 677 } 678 679 if (serviceDirectory.mkdirs()) 680 { 681 try 682 { 683 return storageFactory.getCanonicalName(); 684 } 685 catch (IOException ioe) 686 { 687 serviceDirectory.deleteAll(); 688 throw ioe; 689 } 690 } 691 throw StandardException.newException(SQLState.SERVICE_DIRECTORY_CREATE_ERROR, serviceDirectory); 692 } 693 finally { storageFactory.shutdown(); } 694 } 695 } 696 ); 697 } 698 catch (SecurityException se) { t = se; } 699 catch (PrivilegedActionException pae) 700 { 701 t = pae.getException(); 702 if( t instanceof StandardException) 703 throw (StandardException) t; 704 } 705 706 throw StandardException.newException(SQLState.SERVICE_DIRECTORY_CREATE_ERROR, t, name); 707 } 709 private String getDirectoryPath( String name) 710 { 711 StringBuffer sb = new StringBuffer (); 712 if( home != null) 713 { 714 sb.append( home); 715 sb.append( separatorChar); 716 } 717 if( separatorChar != '/') 718 sb.append( name.replace( '/', separatorChar)); 719 else 720 sb.append( name); 721 return sb.toString(); 722 } 724 public boolean removeServiceRoot(final String serviceName) 725 { 726 if( !( rootStorageFactory instanceof WritableStorageFactory)) 727 return false; 728 try 729 { 730 return AccessController.doPrivileged( 731 new PrivilegedExceptionAction () 732 { 733 public Object run() 734 throws StandardException, IOException , InstantiationException , IllegalAccessException 735 { 736 StorageFactory storageFactory = privGetStorageFactoryInstance( true, serviceName, null, null); 737 try 738 { 739 if (SanityManager.DEBUG) 740 SanityManager.ASSERT(serviceName.equals( storageFactory.getCanonicalName()), serviceName); 741 StorageFile serviceDirectory = storageFactory.newStorageFile( null); 742 return serviceDirectory.deleteAll() ? this : null; 743 } 744 finally { storageFactory.shutdown(); } 745 } 746 } 747 ) != null; 748 } 749 catch( PrivilegedActionException pae){ return false;} 750 } 752 public String getCanonicalServiceName(String name) 753 throws StandardException 754 { 755 String protocolLeadIn = getType() + ":"; 756 int colon = name.indexOf( ':'); 757 if( colon > 1) { 759 if( ! name.startsWith( protocolLeadIn)) 760 return null; name = name.substring( colon + 1); 762 } 763 if( getType().equals( PersistentService.DIRECTORY)) protocolLeadIn = ""; 765 final String nm = name; 766 767 try 768 { 769 return protocolLeadIn + (String ) AccessController.doPrivileged( 770 new PrivilegedExceptionAction () 771 { 772 public Object run() 773 throws StandardException, IOException , InstantiationException , IllegalAccessException 774 { 775 StorageFactory storageFactory = privGetStorageFactoryInstance( true, nm, null, null); 776 try 777 { 778 return storageFactory.getCanonicalName(); 779 } 780 finally { storageFactory.shutdown();} 781 } 782 } 783 ); 784 } 785 catch (PrivilegedActionException pae) 786 { 787 throw Monitor.exceptionStartingModule(pae.getException()); 788 } 789 } 791 public String getUserServiceName(String serviceName) 792 { 793 if (home != null) 794 { 795 if ((serviceName.length() > (canonicalHome.length() + 1)) && serviceName.startsWith(canonicalHome)) 797 { 798 serviceName = serviceName.substring(canonicalHome.length()); 799 if (serviceName.charAt(0) == separatorChar) 800 serviceName = serviceName.substring(1); 801 } 802 } 803 804 return serviceName.replace( separatorChar, '/'); 805 } 806 807 public boolean isSameService(String serviceName1, String serviceName2) 808 { 809 if (SanityManager.DEBUG) 810 { 811 try { 812 SanityManager.ASSERT(serviceName1.equals(getCanonicalServiceName(serviceName1)), serviceName1); 813 SanityManager.ASSERT(serviceName2.equals(getCanonicalServiceName(serviceName2)), serviceName2); 814 } catch (StandardException se) 815 { 816 return false; 817 } 818 } 819 return serviceName1.equals(serviceName2); 820 } 822 823 828 public Class getStorageFactoryClass() 829 { 830 return storageFactoryClass; 831 } 832 833 final class DirectoryList implements Enumeration , PrivilegedAction 834 { 835 private String [] contents; 836 private StorageFile systemDirectory; 837 838 private int index; 839 private boolean validIndex; 840 841 private int actionCode; 842 private static final int INIT_ACTION = 0; 843 private static final int HAS_MORE_ELEMENTS_ACTION = 1; 844 845 DirectoryList() 846 { 847 actionCode = INIT_ACTION; 848 AccessController.doPrivileged( this); 849 } 850 851 public boolean hasMoreElements() 852 { 853 if (validIndex) 854 return true; 855 856 actionCode = HAS_MORE_ELEMENTS_ACTION; 857 return AccessController.doPrivileged( this) != null; 858 } 860 public Object nextElement() throws NoSuchElementException 861 { 862 if (!hasMoreElements()) 863 throw new NoSuchElementException (); 864 865 validIndex = false; 866 return contents[index++]; 867 } 869 public final Object run() 871 { 872 switch( actionCode) 873 { 874 case INIT_ACTION: 875 systemDirectory = rootStorageFactory.newStorageFile( null); 876 contents = systemDirectory.list(); 877 return null; 878 879 case HAS_MORE_ELEMENTS_ACTION: 880 for (; index < contents.length; contents[index++] = null) 881 { 882 try 883 { 884 StorageFactory storageFactory = privGetStorageFactoryInstance( true, contents[index], null, null); 885 try 886 { 887 StorageFile properties = storageFactory.newStorageFile( PersistentService.PROPERTIES_NAME); 888 if (!properties.exists()) 889 continue; 890 contents[index] = storageFactory.getCanonicalName(); 892 validIndex = true; 893 894 return this; 895 } 896 finally { storageFactory.shutdown(); } 897 } 898 catch (Exception se) { continue; } 899 } 900 return null; 901 } 902 return null; 903 } } } 906 | Popular Tags |