Source Code Cross Referenced for RawStore.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » store » raw » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.store.raw 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.store.raw.RawStore
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to you under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.impl.store.raw;
0023:
0024:        import org.apache.derby.iapi.services.daemon.DaemonFactory;
0025:        import org.apache.derby.iapi.services.daemon.DaemonService;
0026:        import org.apache.derby.iapi.services.context.ContextManager;
0027:        import org.apache.derby.iapi.services.context.ContextService;
0028:        import org.apache.derby.iapi.services.crypto.CipherFactoryBuilder;
0029:        import org.apache.derby.iapi.services.crypto.CipherFactory;
0030:        import org.apache.derby.iapi.services.crypto.CipherProvider;
0031:        import org.apache.derby.iapi.services.locks.LockFactory;
0032:        import org.apache.derby.iapi.services.monitor.Monitor;
0033:        import org.apache.derby.iapi.services.monitor.ModuleControl;
0034:        import org.apache.derby.iapi.services.monitor.ModuleSupportable;
0035:        import org.apache.derby.iapi.services.monitor.PersistentService;
0036:        import org.apache.derby.iapi.services.sanity.SanityManager;
0037:
0038:        import org.apache.derby.iapi.error.StandardException;
0039:        import org.apache.derby.iapi.services.i18n.MessageService;
0040:
0041:        import org.apache.derby.iapi.services.property.PersistentSet;
0042:        import org.apache.derby.iapi.store.access.TransactionInfo;
0043:        import org.apache.derby.iapi.store.access.AccessFactoryGlobals;
0044:        import org.apache.derby.iapi.store.access.FileResource;
0045:        import org.apache.derby.iapi.store.raw.ScanHandle;
0046:        import org.apache.derby.iapi.store.raw.RawStoreFactory;
0047:        import org.apache.derby.iapi.store.raw.Transaction;
0048:        import org.apache.derby.iapi.store.raw.xact.RawTransaction;
0049:        import org.apache.derby.iapi.store.raw.xact.TransactionFactory;
0050:        import org.apache.derby.iapi.store.raw.data.DataFactory;
0051:        import org.apache.derby.iapi.store.raw.log.LogFactory;
0052:        import org.apache.derby.iapi.store.raw.log.LogInstant;
0053:        import org.apache.derby.impl.services.monitor.UpdateServiceProperties;
0054:
0055:        import org.apache.derby.io.StorageFactory;
0056:        import org.apache.derby.io.WritableStorageFactory;
0057:        import org.apache.derby.io.StorageFile;
0058:        import org.apache.derby.iapi.store.access.DatabaseInstant;
0059:        import org.apache.derby.catalog.UUID;
0060:        import org.apache.derby.iapi.services.property.PropertyUtil;
0061:        import org.apache.derby.iapi.services.io.FileUtil;
0062:        import org.apache.derby.iapi.util.ReuseFactory;
0063:        import org.apache.derby.iapi.util.StringUtil;
0064:        import org.apache.derby.iapi.reference.Attribute;
0065:        import org.apache.derby.iapi.reference.SQLState;
0066:        import org.apache.derby.iapi.reference.MessageId;
0067:        import org.apache.derby.iapi.reference.Property;
0068:
0069:        import java.security.AccessController;
0070:        import java.security.PrivilegedActionException;
0071:        import java.security.PrivilegedExceptionAction;
0072:        import java.security.SecureRandom;
0073:
0074:        import java.util.Date;
0075:        import java.util.Properties;
0076:        import java.io.Serializable;
0077:        import java.io.File;
0078:        import java.io.FileOutputStream;
0079:        import java.io.FileInputStream;
0080:        import java.io.IOException;
0081:        import java.io.FileNotFoundException;
0082:        import java.io.OutputStreamWriter;
0083:
0084:        import java.net.MalformedURLException;
0085:        import java.net.URL;
0086:
0087:        import java.security.PrivilegedExceptionAction;
0088:        import java.lang.SecurityException;
0089:
0090:        /**
0091:         A Raw store that implements the RawStoreFactory module by delegating all the
0092:         work to the lower modules TransactionFactory, LogFactory and DataFactory.
0093:         <PRE>
0094:         String TransactionFactoryId=<moduleIdentifier>
0095:         </PRE>
0096:        
0097:         <P>
0098:         Class is final as it has methods with privilege blocks
0099:         and implements PrivilegedExceptionAction.
0100:         */
0101:
0102:        public final class RawStore implements  RawStoreFactory, ModuleControl,
0103:                ModuleSupportable, PrivilegedExceptionAction {
0104:            private static final String BACKUP_HISTORY = "BACKUP.HISTORY";
0105:            protected TransactionFactory xactFactory;
0106:            protected DataFactory dataFactory;
0107:            protected LogFactory logFactory;
0108:            private StorageFactory storageFactory;
0109:
0110:            private SecureRandom random;
0111:            private boolean databaseEncrypted;
0112:            private boolean encryptDatabase;
0113:            private CipherProvider encryptionEngine;
0114:            private CipherProvider decryptionEngine;
0115:            private CipherProvider newEncryptionEngine;
0116:            private CipherProvider newDecryptionEngine;
0117:            private CipherFactory currentCipherFactory;
0118:            private CipherFactory newCipherFactory = null;
0119:            private int counter_encrypt;
0120:            private int counter_decrypt;
0121:            private int encryptionBlockSize = RawStoreFactory.DEFAULT_ENCRYPTION_BLOCKSIZE;
0122:
0123:            String dataDirectory; // where files are stored	
0124:
0125:            // this daemon takes care of all daemon work for this raw store
0126:            protected DaemonService rawStoreDaemon;
0127:
0128:            private int actionCode;
0129:            private static final int FILE_WRITER_ACTION = 1;
0130:            private StorageFile actionStorageFile;
0131:            private StorageFile actionToStorageFile;
0132:            private boolean actionAppend;
0133:            private static final int REGULAR_FILE_EXISTS_ACTION = 2;
0134:            private File actionRegularFile;
0135:            private static final int STORAGE_FILE_EXISTS_ACTION = 3;
0136:            private static final int REGULAR_FILE_DELETE_ACTION = 4;
0137:            private static final int REGULAR_FILE_MKDIRS_ACTION = 5;
0138:            private static final int REGULAR_FILE_IS_DIRECTORY_ACTION = 6;
0139:            private static final int REGULAR_FILE_REMOVE_DIRECTORY_ACTION = 7;
0140:            private static final int REGULAR_FILE_RENAME_TO_ACTION = 8;
0141:            private File actionRegularFile2;
0142:            private static final int COPY_STORAGE_DIRECTORY_TO_REGULAR_ACTION = 9;
0143:            private byte[] actionBuffer;
0144:            private String[] actionFilter;
0145:            private boolean actionCopySubDirs;
0146:            private static final int COPY_REGULAR_DIRECTORY_TO_STORAGE_ACTION = 10;
0147:            private static final int COPY_REGULAR_FILE_TO_STORAGE_ACTION = 11;
0148:            private static final int REGULAR_FILE_LIST_DIRECTORY_ACTION = 12;
0149:            private static final int STORAGE_FILE_LIST_DIRECTORY_ACTION = 13;
0150:            private static final int COPY_STORAGE_FILE_TO_REGULAR_ACTION = 14;
0151:            private static final int REGULAR_FILE_GET_CANONICALPATH_ACTION = 15;
0152:            private static final int STORAGE_FILE_GET_CANONICALPATH_ACTION = 16;
0153:            private static final int COPY_STORAGE_FILE_TO_STORAGE_ACTION = 17;
0154:            private static final int STORAGE_FILE_DELETE_ACTION = 18;
0155:
0156:            public RawStore() {
0157:            }
0158:
0159:            /*
0160:             ** Methods of ModuleControl
0161:             */
0162:
0163:            /**
0164:              We use this RawStore for all databases.
0165:             */
0166:            public boolean canSupport(Properties startParams) {
0167:                return true;
0168:            }
0169:
0170:            public void boot(boolean create, Properties properties)
0171:                    throws StandardException {
0172:                dataDirectory = properties.getProperty(PersistentService.ROOT);
0173:                DaemonFactory daemonFactory = (DaemonFactory) Monitor
0174:                        .startSystemModule(org.apache.derby.iapi.reference.Module.DaemonFactory);
0175:                rawStoreDaemon = daemonFactory
0176:                        .createNewDaemon("rawStoreDaemon");
0177:                xactFactory = (TransactionFactory) Monitor
0178:                        .bootServiceModule(create, this ,
0179:                                getTransactionFactoryModule(), properties);
0180:
0181:                dataFactory = (DataFactory) Monitor.bootServiceModule(create,
0182:                        this , getDataFactoryModule(), properties);
0183:                storageFactory = dataFactory.getStorageFactory();
0184:
0185:                String restoreFromBackup = null;
0186:
0187:                if (properties != null) {
0188:                    // check if this is a restore from a backup copy. 
0189:                    restoreFromBackup = properties
0190:                            .getProperty(Attribute.CREATE_FROM);
0191:                    if (restoreFromBackup == null)
0192:                        restoreFromBackup = properties
0193:                                .getProperty(Attribute.RESTORE_FROM);
0194:                    if (restoreFromBackup == null)
0195:                        restoreFromBackup = properties
0196:                                .getProperty(Attribute.ROLL_FORWARD_RECOVERY_FROM);
0197:
0198:                }
0199:
0200:                // setup database encryption engines.
0201:                if (create)
0202:                    setupEncryptionEngines(create, properties);
0203:
0204:                // let everyone knows who their rawStoreFactory is and they can use it
0205:                // to get to other modules
0206:                // pass in create and properties to dataFactory so it can boot the log
0207:                // factory
0208:
0209:                dataFactory.setRawStoreFactory(this , create, properties);
0210:                xactFactory.setRawStoreFactory(this );
0211:
0212:                if (properties instanceof  UpdateServiceProperties) {
0213:                    if (storageFactory instanceof  WritableStorageFactory)
0214:                        ((UpdateServiceProperties) properties)
0215:                                .setStorageFactory((WritableStorageFactory) storageFactory);
0216:                }
0217:
0218:                // log factory is booted by the data factory
0219:                logFactory = (LogFactory) Monitor.findServiceModule(this ,
0220:                        getLogFactoryModule());
0221:
0222:                //save the service properties to a file if we are doing a restore from
0223:                if (restoreFromBackup != null) {
0224:                    //copy the jar files.etc from backup if they don't exist
0225:                    restoreRemainingFromBackup(restoreFromBackup);
0226:                    ((UpdateServiceProperties) properties)
0227:                            .saveServiceProperties();
0228:                }
0229:
0230:                // If the log is at another location, make sure  service.properties
0231:                // file has it.
0232:                String logDevice = properties.getProperty(Attribute.LOG_DEVICE);
0233:                if (logDevice != null) {
0234:                    if (!isReadOnly() // We do not care about log location if read only
0235:                            && (create
0236:                                    || !logDevice.equals(logFactory
0237:                                            .getCanonicalLogPath()) || restoreFromBackup != null)) {
0238:                        // get the real location from the log factory
0239:                        properties.put(Attribute.LOG_DEVICE, logFactory
0240:                                .getCanonicalLogPath());
0241:                        //make the log device param stored in backup is same as current log device.
0242:                        properties.put(Property.LOG_DEVICE_AT_BACKUP,
0243:                                logFactory.getCanonicalLogPath());
0244:                    }
0245:
0246:                } else {
0247:                    //when we restore from a backup logDevice param does not exists 
0248:                    //in service.properties to support restore using OS commands to work. 
0249:                    //Instead of logDevice, we user logDeviceWhenBackedUp parameter to
0250:                    //identify the log location while restoring createFrom/restoreFrom/rollForwardRecoveryFrom
0251:                    //attribute , following make sures the logDevice parameter gets 
0252:                    //into service.propertues in such cases.
0253:                    if (restoreFromBackup != null
0254:                            && logFactory.getCanonicalLogPath() != null) {
0255:                        //logdevice might have got changed because of backup restore. 
0256:                        properties.put(Attribute.LOG_DEVICE, logFactory
0257:                                .getCanonicalLogPath());
0258:                    } else {
0259:                        //might have been OS copy restore. We default log to db home
0260:                        properties.remove(Property.LOG_DEVICE_AT_BACKUP);
0261:                    }
0262:                }
0263:
0264:                //save the service properties to a file if we are doing a restore from
0265:                if (restoreFromBackup != null) {
0266:                    //copy the jar files.etc from backup if they don't exist
0267:                    restoreRemainingFromBackup(restoreFromBackup);
0268:                    ((UpdateServiceProperties) properties)
0269:                            .saveServiceProperties();
0270:                }
0271:
0272:                /**
0273:                 * Note: service.properties file acts as flags to indicate
0274:                 * that the copy from backup is successful.
0275:                 * If we reached so far while restoring from backup means
0276:                 * we copied all the necessary data from backup. Only thing
0277:                 * that remains is roll forwarding the logs. Incase if we crash at this
0278:                 * point and user re boots the datbase again without any restore flags
0279:                 * it shoud boot without any problem.
0280:                 **/
0281:
0282:                // setup database encryption engine
0283:                if (!create) {
0284:                    // check if the engine crashed while re-encrypting an 
0285:                    // encrypted database or while encryption and 
0286:                    // existing database.
0287:                    if (properties
0288:                            .getProperty(RawStoreFactory.DB_ENCRYPTION_STATUS) != null) {
0289:                        handleIncompleteDatabaseEncryption(properties);
0290:                    }
0291:
0292:                    setupEncryptionEngines(create, properties);
0293:                }
0294:
0295:                if (databaseEncrypted) {
0296:                    // let log factory know if the database is encrypted . 
0297:                    logFactory.setDatabaseEncrypted(false);
0298:                    // let data factory know if the database is encrypted. 
0299:                    dataFactory.setDatabaseEncrypted();
0300:                }
0301:
0302:                // no need to tell log factory which raw store factory it belongs to
0303:                // since this is passed into the log factory for recovery
0304:                // after the factories are loaded, recover the database
0305:                logFactory.recover(this , dataFactory, xactFactory);
0306:
0307:                // if user requested to encrpty an unecrypted database or encrypt with
0308:                // new alogorithm then do that now.  
0309:                if (encryptDatabase) {
0310:                    configureDatabaseForEncryption(properties, newCipherFactory);
0311:                }
0312:            }
0313:
0314:            public void stop() {
0315:
0316:                if (SanityManager.DEBUG) {
0317:                    if (databaseEncrypted)
0318:                        SanityManager.DEBUG_PRINT("encryption statistics",
0319:                                "Encryption called " + counter_encrypt
0320:                                        + " times, " + "decryption called "
0321:                                        + counter_decrypt + " times");
0322:                }
0323:
0324:                if (rawStoreDaemon != null)
0325:                    rawStoreDaemon.stop();
0326:
0327:                if (logFactory == null)
0328:                    return;
0329:
0330:                try {
0331:
0332:                    if (logFactory.checkpoint(this , dataFactory, xactFactory,
0333:                            false)) {
0334:                        if (dataFactory != null)
0335:                            dataFactory.removeStubsOK();
0336:                    }
0337:
0338:                } catch (StandardException se) {
0339:                    // checkpoint failed, stop all factory from shutting down normally
0340:                    markCorrupt(se);
0341:                }
0342:            }
0343:
0344:            /*
0345:             ** Methods of RawStoreFactory
0346:             */
0347:
0348:            /**
0349:            	Is the store read-only.
0350:            	@see RawStoreFactory#isReadOnly
0351:             */
0352:            public boolean isReadOnly() {
0353:                return dataFactory.isReadOnly();
0354:            }
0355:
0356:            public LockFactory getLockFactory() {
0357:                return xactFactory.getLockFactory();
0358:            }
0359:
0360:            /**
0361:            	Get the Transaction Factory to use with this store.
0362:             */
0363:            public TransactionFactory getXactFactory() {
0364:                return xactFactory;
0365:            }
0366:
0367:            /*
0368:             * Return the module providing XAresource interface to the transaction
0369:             * table.
0370:             *
0371:             * @exception StandardException Standard cloudscape exception policy.
0372:             */
0373:            public/* XAResourceManager */Object getXAResourceManager()
0374:                    throws StandardException {
0375:                return (xactFactory.getXAResourceManager());
0376:            }
0377:
0378:            public Transaction startGlobalTransaction(
0379:                    ContextManager contextMgr, int format_id, byte[] global_id,
0380:                    byte[] branch_id) throws StandardException {
0381:                return xactFactory.startGlobalTransaction(this , contextMgr,
0382:                        format_id, global_id, branch_id);
0383:            }
0384:
0385:            public Transaction startTransaction(ContextManager contextMgr,
0386:                    String transName) throws StandardException {
0387:                return xactFactory
0388:                        .startTransaction(this , contextMgr, transName);
0389:            }
0390:
0391:            public Transaction startNestedReadOnlyUserTransaction(
0392:                    Object compatibilitySpace, ContextManager contextMgr,
0393:                    String transName) throws StandardException {
0394:                return (xactFactory.startNestedReadOnlyUserTransaction(this ,
0395:                        compatibilitySpace, contextMgr, transName));
0396:            }
0397:
0398:            public Transaction startNestedUpdateUserTransaction(
0399:                    ContextManager contextMgr, String transName)
0400:                    throws StandardException {
0401:                return (xactFactory.startNestedUpdateUserTransaction(this ,
0402:                        contextMgr, transName));
0403:            }
0404:
0405:            public Transaction findUserTransaction(ContextManager contextMgr,
0406:                    String transName) throws StandardException {
0407:                return xactFactory.findUserTransaction(this , contextMgr,
0408:                        transName);
0409:            }
0410:
0411:            public Transaction startInternalTransaction(
0412:                    ContextManager contextMgr) throws StandardException {
0413:
0414:                return xactFactory.startInternalTransaction(this , contextMgr);
0415:            }
0416:
0417:            public void checkpoint() throws StandardException {
0418:                logFactory.checkpoint(this , dataFactory, xactFactory, false);
0419:            }
0420:
0421:            public void freeze() throws StandardException {
0422:                logFactory.checkpoint(this , dataFactory, xactFactory, true);
0423:                dataFactory.freezePersistentStore();
0424:                logFactory.freezePersistentStore();
0425:            }
0426:
0427:            public void unfreeze() throws StandardException {
0428:                logFactory.unfreezePersistentStore();
0429:                dataFactory.unfreezePersistentStore();
0430:            }
0431:
0432:            /**
0433:             * Backup the database to a backup directory.
0434:             *
0435:             * @param backupDir the name of the directory where the backup should be
0436:             *                  stored. This directory will be created if it 
0437:             *                  does not exist.
0438:             * @param wait if <tt>true</tt>, waits for  all the backup blocking 
0439:             *             operations in progress to finish.
0440:             * @exception StandardException thrown on error
0441:             */
0442:            public void backup(String backupDir, boolean wait)
0443:                    throws StandardException {
0444:                if (backupDir == null || backupDir.equals("")) {
0445:                    throw StandardException.newException(
0446:                            SQLState.RAWSTORE_CANNOT_CREATE_BACKUP_DIRECTORY,
0447:                            (File) null);
0448:                }
0449:
0450:                // in case this is an URL form
0451:                String backupDirURL = null;
0452:                try {
0453:                    URL url = new URL(backupDir);
0454:                    backupDirURL = url.getFile();
0455:                } catch (MalformedURLException ex) {
0456:                }
0457:
0458:                if (backupDirURL != null)
0459:                    backupDir = backupDirURL;
0460:
0461:                // find the user transaction, it is necessary for online backup 
0462:                // to open the container through page cache
0463:                RawTransaction t = xactFactory.findUserTransaction(this ,
0464:                        ContextService.getFactory().getCurrentContextManager(),
0465:                        AccessFactoryGlobals.USER_TRANS_NAME);
0466:
0467:                try {
0468:
0469:                    // check if  any backup blocking operations are in progress
0470:                    // in the same transaction backup is being executed? Backup is 
0471:                    // not allowed if the transaction has uncommitted
0472:                    // unlogged operations that are blocking the backup.
0473:
0474:                    if (t.isBlockingBackup()) {
0475:                        throw StandardException
0476:                                .newException(SQLState.BACKUP_OPERATIONS_NOT_ALLOWED);
0477:                    }
0478:
0479:                    // check if any backup blocking operations are in progress
0480:                    // and stop new ones from starting until the backup is completed.
0481:                    if (!xactFactory.blockBackupBlockingOperations(wait)) {
0482:                        throw StandardException
0483:                                .newException(SQLState.BACKUP_BLOCKING_OPERATIONS_IN_PROGRESS);
0484:                    }
0485:
0486:                    // perform backup
0487:                    backup(t, new File(backupDir));
0488:                } finally {
0489:                    // let the xactfatory know that backup is done, so that
0490:                    // it can allow backup blocking operations. 
0491:                    xactFactory.unblockBackupBlockingOperations();
0492:                }
0493:            }
0494:
0495:            /*
0496:             * Backup the database.
0497:             * Online backup copies all the database files (log, seg0  ...Etc) to the
0498:             * specified backup location without blocking any user operation for the 
0499:             * duration of the backup. Stable copy is made of each page using 
0500:             * page level latches and in some cases with the help of monitors.  
0501:             * Transaction log is also backed up, this is used to bring the database to 
0502:             * the consistent state on restore.
0503:             * 
0504:             * <P> MT- only one thread  is allowed to perform backup at any given time. 
0505:             *  Synchronized on this. Parallel backups are not supported. 
0506:             */
0507:            public synchronized void backup(Transaction t, File backupDir)
0508:                    throws StandardException {
0509:                if (!privExists(backupDir)) {
0510:                    // if backup dir does not exist, go ahead and create it.
0511:
0512:                    if (!privMkdirs(backupDir)) {
0513:                        throw StandardException
0514:                                .newException(
0515:                                        SQLState.RAWSTORE_CANNOT_CREATE_BACKUP_DIRECTORY,
0516:                                        (File) backupDir);
0517:                    }
0518:                } else {
0519:                    // entity with backup name exists, make sure it is a directory.
0520:
0521:                    if (!privIsDirectory(backupDir)) {
0522:                        throw StandardException
0523:                                .newException(
0524:                                        SQLState.RAWSTORE_CANNOT_BACKUP_TO_NONDIRECTORY,
0525:                                        (File) backupDir);
0526:                    }
0527:
0528:                    // check if a user has given the backup as a database directory by
0529:                    // mistake, backup path can not be a derby database directory. 
0530:                    // If a directory contains PersistentService.PROPERTIES_NAME, it 
0531:                    // is assumed to be a derby database directory because derby 
0532:                    // databases always have this file. 
0533:
0534:                    if (privExists(new File(backupDir,
0535:                            PersistentService.PROPERTIES_NAME))) {
0536:                        throw StandardException
0537:                                .newException(
0538:                                        SQLState.RAWSTORE_CANNOT_BACKUP_INTO_DATABASE_DIRECTORY,
0539:                                        (File) backupDir);
0540:                    }
0541:                }
0542:
0543:                boolean error = true;
0544:                boolean renamed = false;
0545:                boolean renameFailed = false;
0546:                File oldbackup = null;
0547:                File backupcopy = null;
0548:                OutputStreamWriter historyFile = null;
0549:                StorageFile dbHistoryFile = null;
0550:                File backupHistoryFile = null;
0551:                LogInstant backupInstant = logFactory
0552:                        .getFirstUnflushedInstant();
0553:
0554:                try {
0555:                    // get name of the current db, ie. database directory of current db.
0556:                    StorageFile dbase = storageFactory.newStorageFile(null);
0557:                    String canonicalDbName = storageFactory.getCanonicalName();
0558:                    int lastSep = canonicalDbName.lastIndexOf(storageFactory
0559:                            .getSeparator());
0560:                    String dbname = canonicalDbName.substring(lastSep + 1);
0561:
0562:                    // append to end of history file
0563:                    historyFile = privFileWriter(storageFactory
0564:                            .newStorageFile(BACKUP_HISTORY), true);
0565:
0566:                    backupcopy = new File(backupDir, dbname);
0567:
0568:                    logHistory(historyFile, MessageService.getTextMessage(
0569:                            MessageId.STORE_BACKUP_STARTED, canonicalDbName,
0570:                            getFilePath(backupcopy)));
0571:
0572:                    // check if a backup copy of this database already exists,
0573:                    if (privExists(backupcopy)) {
0574:                        // first make a backup of the backup
0575:                        oldbackup = new File(backupDir, dbname + ".OLD");
0576:                        if (privExists(oldbackup)) {
0577:                            if (privIsDirectory(oldbackup))
0578:                                privRemoveDirectory(oldbackup);
0579:                            else
0580:                                privDelete(oldbackup);
0581:                        }
0582:
0583:                        if (!privRenameTo(backupcopy, oldbackup)) {
0584:                            renameFailed = true;
0585:                            throw StandardException.newException(
0586:                                    SQLState.RAWSTORE_ERROR_RENAMING_FILE,
0587:                                    backupcopy, oldbackup);
0588:                        } else {
0589:                            logHistory(historyFile, MessageService
0590:                                    .getTextMessage(
0591:                                            MessageId.STORE_MOVED_BACKUP,
0592:                                            getFilePath(backupcopy),
0593:                                            getFilePath(oldbackup)));
0594:                            renamed = true;
0595:                        }
0596:                    }
0597:
0598:                    // create the backup database directory
0599:                    if (!privMkdirs(backupcopy)) {
0600:                        throw StandardException
0601:                                .newException(
0602:                                        SQLState.RAWSTORE_CANNOT_CREATE_BACKUP_DIRECTORY,
0603:                                        (File) backupcopy);
0604:                    }
0605:
0606:                    dbHistoryFile = storageFactory
0607:                            .newStorageFile(BACKUP_HISTORY);
0608:                    backupHistoryFile = new File(backupcopy, BACKUP_HISTORY);
0609:
0610:                    // copy the history file into the backup. 
0611:                    if (!privCopyFile(dbHistoryFile, backupHistoryFile))
0612:                        throw StandardException.newException(
0613:                                SQLState.RAWSTORE_ERROR_COPYING_FILE,
0614:                                dbHistoryFile, backupHistoryFile);
0615:
0616:                    // if they are any jar file stored in the database, copy them into
0617:                    // the backup. 
0618:                    StorageFile jarDir = storageFactory
0619:                            .newStorageFile(FileResource.JAR_DIRECTORY_NAME);
0620:
0621:                    if (privExists(jarDir)) {
0622:                        // find the list of schema directories under the jar dir and
0623:                        // then copy only the plain files under those directories. One 
0624:                        // could just use the recursive copy of directory to copy all 
0625:                        // the files under the jar dir, but the problem with that is if
0626:                        // a user gives jar directory as the backup path by mistake, 
0627:                        // copy will fail while copying the backup dir onto itself in 
0628:                        // recursion
0629:
0630:                        String[] jarSchemaList = privList(jarDir);
0631:                        File backupJarDir = new File(backupcopy,
0632:                                FileResource.JAR_DIRECTORY_NAME);
0633:                        // Create the backup jar directory
0634:                        if (!privMkdirs(backupJarDir)) {
0635:                            throw StandardException
0636:                                    .newException(
0637:                                            SQLState.RAWSTORE_CANNOT_CREATE_BACKUP_DIRECTORY,
0638:                                            (File) backupJarDir);
0639:                        }
0640:
0641:                        for (int i = 0; i < jarSchemaList.length; i++) {
0642:                            StorageFile jarSchemaDir = storageFactory
0643:                                    .newStorageFile(jarDir, jarSchemaList[i]);
0644:                            File backupJarSchemaDir = new File(backupJarDir,
0645:                                    jarSchemaList[i]);
0646:
0647:                            if (!privCopyDirectory(jarSchemaDir,
0648:                                    backupJarSchemaDir, (byte[]) null, null,
0649:                                    false)) {
0650:                                throw StandardException.newException(
0651:                                        SQLState.RAWSTORE_ERROR_COPYING_FILE,
0652:                                        jarSchemaDir, backupJarSchemaDir);
0653:                            }
0654:                        }
0655:                    }
0656:
0657:                    // save service properties into the backup, Read in property 
0658:                    // from service.properties file, remove logDevice from it, 
0659:                    // then write it to the backup.
0660:
0661:                    StorageFile logdir = logFactory.getLogDirectory();
0662:
0663:                    try {
0664:                        String name = Monitor.getMonitor().getServiceName(this );
0665:                        PersistentService ps = Monitor.getMonitor()
0666:                                .getServiceType(this );
0667:                        String fullName = ps.getCanonicalServiceName(name);
0668:                        Properties prop = ps.getServiceProperties(fullName,
0669:                                (Properties) null);
0670:
0671:                        StorageFile defaultLogDir = storageFactory
0672:                                .newStorageFile(LogFactory.LOG_DIRECTORY_NAME);
0673:
0674:                        if (!logdir.equals(defaultLogDir)) {
0675:                            prop.remove(Attribute.LOG_DEVICE);
0676:                            if (SanityManager.DEBUG) {
0677:                                SanityManager
0678:                                        .ASSERT(
0679:                                                prop
0680:                                                        .getProperty(Attribute.LOG_DEVICE) == null,
0681:                                                "cannot get rid of logDevice property");
0682:                            }
0683:
0684:                            logHistory(
0685:                                    historyFile,
0686:                                    MessageService
0687:                                            .getTextMessage(MessageId.STORE_EDITED_SERVICEPROPS));
0688:                        }
0689:
0690:                        // save the service properties into the backup.
0691:                        ps.saveServiceProperties(backupcopy.getPath(), prop,
0692:                                false);
0693:
0694:                    } catch (StandardException se) {
0695:                        logHistory(
0696:                                historyFile,
0697:                                MessageService
0698:                                        .getTextMessage(MessageId.STORE_ERROR_EDIT_SERVICEPROPS)
0699:                                        + se);
0700:
0701:                        return; // skip the rest and let finally block clean up
0702:                    }
0703:
0704:                    // Incase of encrypted database and the key is an external 
0705:                    // encryption key, there is an extra file with name  
0706:                    // Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE, this file should be
0707:                    // copied in to the backup.
0708:                    StorageFile verifyKeyFile = storageFactory
0709:                            .newStorageFile(Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE);
0710:                    if (privExists(verifyKeyFile)) {
0711:                        File backupVerifyKeyFile = new File(backupcopy,
0712:                                Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE);
0713:
0714:                        if (!privCopyFile(verifyKeyFile, backupVerifyKeyFile))
0715:                            throw StandardException.newException(
0716:                                    SQLState.RAWSTORE_ERROR_COPYING_FILE,
0717:                                    verifyKeyFile, backupVerifyKeyFile);
0718:                    }
0719:
0720:                    File logBackup = new File(backupcopy,
0721:                            LogFactory.LOG_DIRECTORY_NAME);
0722:
0723:                    // this is wierd, delete it
0724:                    if (privExists(logBackup)) {
0725:                        privRemoveDirectory(logBackup);
0726:                    }
0727:
0728:                    // Create the log directory
0729:                    if (!privMkdirs(logBackup)) {
0730:                        throw StandardException
0731:                                .newException(
0732:                                        SQLState.RAWSTORE_CANNOT_CREATE_BACKUP_DIRECTORY,
0733:                                        (File) logBackup);
0734:                    }
0735:
0736:                    // do a checkpoint to get the persistent store up to date.
0737:                    logFactory.checkpoint(this , dataFactory, xactFactory, true);
0738:
0739:                    // start the transaction log  backup. 
0740:                    logFactory.startLogBackup(logBackup);
0741:
0742:                    File segBackup = new File(backupcopy, "seg0");
0743:
0744:                    // Create the data segment directory
0745:                    if (!privMkdirs(segBackup)) {
0746:                        throw StandardException
0747:                                .newException(
0748:                                        SQLState.RAWSTORE_CANNOT_CREATE_BACKUP_DIRECTORY,
0749:                                        (File) segBackup);
0750:                    }
0751:
0752:                    // backup all the information in the data segment.
0753:                    dataFactory.backupDataFiles(t, segBackup);
0754:
0755:                    logHistory(historyFile, MessageService.getTextMessage(
0756:                            MessageId.STORE_DATA_SEG_BACKUP_COMPLETED,
0757:                            getFilePath(segBackup)));
0758:
0759:                    // copy the log that got generated after the backup started to
0760:                    // backup location and tell the logfactory that backup has come 
0761:                    // to end.
0762:                    logFactory.endLogBackup(logBackup);
0763:
0764:                    logHistory(historyFile, MessageService.getTextMessage(
0765:                            MessageId.STORE_COPIED_LOG, getFilePath(logdir),
0766:                            getFilePath(logBackup)));
0767:
0768:                    error = false;
0769:                } catch (IOException ioe) {
0770:                    throw StandardException.newException(
0771:                            SQLState.RAWSTORE_UNEXPECTED_EXCEPTION, ioe);
0772:                } finally {
0773:
0774:                    try {
0775:                        if (error) {
0776:
0777:                            // Abort all activity related to backup in the log factory.
0778:                            logFactory.abortLogBackup();
0779:
0780:                            // remove the half backed up copy
0781:                            // unless the error occured during  rename process;
0782:                            // inwhich case 'backupcopy' refers to the previous backup
0783:                            // not an half backed one.
0784:                            if (!renameFailed)
0785:                                privRemoveDirectory(backupcopy);
0786:
0787:                            if (renamed)
0788:                                // recover the old backup
0789:                                privRenameTo(oldbackup, backupcopy);
0790:
0791:                            logHistory(
0792:                                    historyFile,
0793:                                    MessageService
0794:                                            .getTextMessage(MessageId.STORE_BACKUP_ABORTED));
0795:
0796:                        } else {
0797:                            // success, remove the old backup copy
0798:                            if (renamed && privExists(oldbackup)) {
0799:                                // get rid of the old backup
0800:                                privRemoveDirectory(oldbackup);
0801:                                logHistory(historyFile, MessageService
0802:                                        .getTextMessage(
0803:                                                MessageId.STORE_REMOVED_BACKUP,
0804:                                                getFilePath(oldbackup)));
0805:                            }
0806:                            logHistory(historyFile, MessageService
0807:                                    .getTextMessage(
0808:                                            MessageId.STORE_BACKUP_COMPLETED,
0809:                                            backupInstant));
0810:
0811:                            // copy the updated version of history file with current
0812:                            // backup information into the backup.
0813:                            if (!privCopyFile(dbHistoryFile, backupHistoryFile))
0814:                                throw StandardException.newException(
0815:                                        SQLState.RAWSTORE_ERROR_COPYING_FILE,
0816:                                        dbHistoryFile, backupHistoryFile);
0817:                        }
0818:
0819:                        historyFile.close();
0820:                    } catch (IOException ioe) {
0821:                        try {
0822:                            historyFile.close();
0823:                        } catch (IOException ioe2) {
0824:                        }
0825:                        ;
0826:                        throw StandardException.newException(
0827:                                SQLState.RAWSTORE_UNEXPECTED_EXCEPTION, ioe);
0828:                    }
0829:                }
0830:
0831:            }
0832:
0833:            /**
0834:             * Backup the database to a backup directory and enable the log archive
0835:             * mode that will keep the archived log files required for roll-forward
0836:             * from this version backup.
0837:             *
0838:             * @param backupDir the name of the directory where the backup should be
0839:             *                  stored. This directory will be created if it 
0840:             *                  does not exist.   
0841:             *
0842:             * @param deleteOnlineArchivedLogFiles  
0843:             *                  If true deletes online archived 
0844:             *                  log files that exist before this backup, delete 
0845:             *                  will occur  only after the backup is  complete.
0846:             *
0847:             * @param wait      if <tt>true</tt>, waits for  all the backup blocking 
0848:             *                  operations in progress to finish.
0849:             *
0850:             * @exception StandardException thrown on error.
0851:             */
0852:            public void backupAndEnableLogArchiveMode(String backupDir,
0853:                    boolean deleteOnlineArchivedLogFiles, boolean wait)
0854:                    throws StandardException {
0855:                boolean enabledLogArchive = false;
0856:                try {
0857:                    // Enable the log archive mode, if it is not already enabled.
0858:                    if (!logFactory.logArchived()) {
0859:                        logFactory.enableLogArchiveMode();
0860:                        enabledLogArchive = true;
0861:                    }
0862:
0863:                    backup(backupDir, wait);
0864:
0865:                    // After successful backup delete the archived log files
0866:                    // that are not necessary to do a roll-forward recovery
0867:                    // from this backup if requested.
0868:                    if (deleteOnlineArchivedLogFiles) {
0869:                        logFactory.deleteOnlineArchivedLogFiles();
0870:                    }
0871:                } catch (Throwable error) {
0872:                    // On any errors , disable the log archive, if it 
0873:                    // is enabled on this call. 
0874:                    if (enabledLogArchive)
0875:                        logFactory.disableLogArchiveMode();
0876:                    throw StandardException.plainWrapException(error);
0877:                }
0878:            }
0879:
0880:            /*
0881:             * Disable the log archive mode and delete the archived log files 
0882:             * if requested. 
0883:             *
0884:             * @param deleteOnlineArchivedLogFiles  
0885:             *              If true deletes online archived 
0886:             *              log files that exist before this backup, delete 
0887:             *              will occur  only after the backup is  complete.
0888:             * @exception StandardException thrown on error.
0889:             */
0890:            public void disableLogArchiveMode(
0891:                    boolean deleteOnlineArchivedLogFiles)
0892:                    throws StandardException {
0893:                logFactory.disableLogArchiveMode();
0894:                if (deleteOnlineArchivedLogFiles) {
0895:                    logFactory.deleteOnlineArchivedLogFiles();
0896:                }
0897:            }
0898:
0899:            //copies the files from the backup that does not need
0900:            //any special handling like jars.
0901:            private void restoreRemainingFromBackup(String backupPath)
0902:                    throws StandardException {
0903:                /** 
0904:                 *copy the files from the backup except the ones that we already
0905:                 *copied in the boot methods(like log directory and data segments)
0906:                 *AND Service.properties file which we create last to
0907:                 *indicate the end of copy from backup.
0908:                 */
0909:
0910:                File backuploc = new File(backupPath);
0911:                String[] fromList = privList(backuploc);
0912:                for (int i = 0; i < fromList.length; i++) {
0913:                    StorageFile toFile = storageFactory
0914:                            .newStorageFile(fromList[i]);
0915:                    if (privExists(toFile)
0916:                            || fromList[i]
0917:                                    .equals(PersistentService.PROPERTIES_NAME)) {
0918:                        continue;
0919:                    }
0920:
0921:                    File fromFile = new File(backuploc, fromList[i]);
0922:                    if (privIsDirectory(fromFile)) {
0923:                        if (!privCopyDirectory(fromFile, toFile)) {
0924:                            throw StandardException.newException(
0925:                                    SQLState.UNABLE_TO_COPY_FILE_FROM_BACKUP,
0926:                                    fromFile, toFile);
0927:                        }
0928:                    } else {
0929:                        if (!privCopyFile(fromFile, toFile)) {
0930:                            throw StandardException.newException(
0931:                                    SQLState.UNABLE_TO_COPY_FILE_FROM_BACKUP,
0932:                                    fromFile, toFile);
0933:                        }
0934:                    }
0935:                }
0936:            }
0937:
0938:            public void idle() throws StandardException {
0939:                dataFactory.idle();
0940:            }
0941:
0942:            public TransactionInfo[] getTransactionInfo() {
0943:                return xactFactory.getTransactionInfo();
0944:            }
0945:
0946:            public ScanHandle openFlushedScan(DatabaseInstant start,
0947:                    int groupsIWant) throws StandardException {
0948:                return logFactory.openFlushedScan(start, groupsIWant);
0949:            }
0950:
0951:            public DaemonService getDaemon() {
0952:                return rawStoreDaemon;
0953:            }
0954:
0955:            public void createFinished() throws StandardException {
0956:                xactFactory.createFinished();
0957:                dataFactory.createFinished();
0958:            }
0959:
0960:            /**
0961:             * Get JBMS properties relavent to raw store
0962:             * @exception StandardException Standard Cloudscape Error Policy
0963:             */
0964:            public void getRawStoreProperties(PersistentSet set)
0965:                    throws StandardException {
0966:                logFactory.getLogFactoryProperties(set);
0967:            }
0968:
0969:            /*
0970:             ** backup restore
0971:             */
0972:            /**
0973:            	Freeze persistent store.  Reads can still happen, only cannot write.
0974:            	@exception StandardException Standard Cloudscape Error Policy
0975:             */
0976:            public void freezePersistentStore() throws StandardException {
0977:                // do a checkpoint to get the persistent store up to date.
0978:                logFactory.checkpoint(this , dataFactory, xactFactory, true);
0979:                logFactory.freezePersistentStore();
0980:
0981:            }
0982:
0983:            /**
0984:            	Freeze persistent store.  Reads can still happen, only cannot write.
0985:            	@exception StandardException Standard Cloudscape Error Policy
0986:             */
0987:            public void unfreezePersistentStore() throws StandardException {
0988:                logFactory.unfreezePersistentStore();
0989:            }
0990:
0991:            /*
0992:             ** data encryption/decryption support
0993:             */
0994:
0995:            /*
0996:             * Setup Encryption Engines. 
0997:             */
0998:            private void setupEncryptionEngines(boolean create,
0999:                    Properties properties) throws StandardException {
1000:
1001:                // check if user has requested to encrypt the database or it is an
1002:                // encrypted database.
1003:
1004:                String dataEncryption = properties
1005:                        .getProperty(Attribute.DATA_ENCRYPTION);
1006:                databaseEncrypted = Boolean.valueOf(dataEncryption)
1007:                        .booleanValue();
1008:
1009:                boolean reEncrypt = false;
1010:
1011:                if (!create) {
1012:                    // check if database is already encrypted, by directly peeking at the
1013:                    // database service propertes instead of the properties passed 
1014:                    // to this method. By looking at properties to the boot method ,
1015:                    // one can not differentiate if user is requesting for database
1016:                    // encryption or the database is already encrypted because 
1017:                    // Attribute.DATA_ENCRYPTION is used  to store in the 
1018:                    // service properties to indicate that database
1019:                    // is encrypted and also users can specify it as URL attribute 
1020:                    // to encrypt and existing database. 
1021:
1022:                    String name = Monitor.getMonitor().getServiceName(this );
1023:                    PersistentService ps = Monitor.getMonitor().getServiceType(
1024:                            this );
1025:                    String canonicalName = ps.getCanonicalServiceName(name);
1026:                    Properties serviceprops = ps.getServiceProperties(
1027:                            canonicalName, (Properties) null);
1028:                    dataEncryption = serviceprops
1029:                            .getProperty(Attribute.DATA_ENCRYPTION);
1030:                    boolean encryptedDatabase = Boolean.valueOf(dataEncryption)
1031:                            .booleanValue();
1032:
1033:                    if (!encryptedDatabase && databaseEncrypted) {
1034:                        // it it not an encrypted database, user is asking to 
1035:                        // encrypt an un-encrypted database. 
1036:                        encryptDatabase = true;
1037:                        // set database as un-encrypted, we will set it as encrypted 
1038:                        // after encrypting the existing data. 
1039:                        databaseEncrypted = false;
1040:                    } else {
1041:                        // check if the user has requested to renecrypt  an
1042:                        // encrypted datbase with new encryption password/key.
1043:                        if (encryptedDatabase) {
1044:                            if (properties
1045:                                    .getProperty(Attribute.NEW_BOOT_PASSWORD) != null) {
1046:                                reEncrypt = true;
1047:                            } else if (properties
1048:                                    .getProperty(Attribute.NEW_CRYPTO_EXTERNAL_KEY) != null) {
1049:                                reEncrypt = true;
1050:                            }
1051:                            ;
1052:                            encryptDatabase = reEncrypt;
1053:                        }
1054:
1055:                    }
1056:
1057:                    // NOTE: if user specifies Attribute.DATA_ENCRYPTION on the
1058:                    // connection URL by mistake on an already encrypted database, 
1059:                    // it is ignored.
1060:
1061:                    // prevent attempt to (re)encrypt of a read-only database
1062:                    if (encryptDatabase) {
1063:                        if (isReadOnly()) {
1064:                            if (reEncrypt)
1065:                                throw StandardException
1066:                                        .newException(SQLState.CANNOT_REENCRYPT_READONLY_DATABASE);
1067:                            else
1068:                                throw StandardException
1069:                                        .newException(SQLState.CANNOT_ENCRYPT_READONLY_DATABASE);
1070:                        }
1071:                    }
1072:                }
1073:
1074:                // setup encryption engines. 
1075:                if (databaseEncrypted || encryptDatabase) {
1076:                    // check if database is configured for encryption, during
1077:                    // configuration  some of the properties database; so that
1078:                    // user does not have to specify them on the URL everytime.
1079:                    // Incase of re-encryption of an already of encrypted database
1080:                    // only some information needs to updated; it is not treated 
1081:                    // like the configuring the database for encryption first time. 
1082:                    boolean setupEncryption = create
1083:                            || (encryptDatabase && !reEncrypt);
1084:
1085:                    // start the cipher factory module, that is is used to create 
1086:                    // instances of the cipher factory with specific enctyption 
1087:                    // properties. 
1088:
1089:                    CipherFactoryBuilder cb = (CipherFactoryBuilder) Monitor
1090:                            .startSystemModule(org.apache.derby.iapi.reference.Module.CipherFactoryBuilder);
1091:
1092:                    // create instance of the cipher factory with the 
1093:                    // specified encryption properties. 
1094:                    currentCipherFactory = cb.createCipherFactory(
1095:                            setupEncryption, properties, false);
1096:
1097:                    // The database can be encrypted using an encryption key that is given at
1098:                    // connection url. For security reasons, this key is not made persistent
1099:                    // in the database. But it is necessary to verify the encryption key 
1100:                    // whenever booting the database if it is similar to the key that was used
1101:                    // during creation time. This needs to happen before we access the data/logs to 
1102:                    // avoid the risk of corrupting the database because of a wrong encryption key.
1103:
1104:                    // Please note this verification process does not provide any added security
1105:                    // but is intended to allow to fail gracefully if a wrong encryption key 
1106:                    // is used during boot time
1107:
1108:                    currentCipherFactory.verifyKey(setupEncryption,
1109:                            storageFactory, properties);
1110:
1111:                    // Initializes the encryption and decryption engines
1112:                    encryptionEngine = currentCipherFactory
1113:                            .createNewCipher(CipherFactory.ENCRYPT);
1114:
1115:                    // At creation time of an encrypted database, store the encryption block size
1116:                    // for the algorithm. Store this value as property given by  
1117:                    // RawStoreFactory.ENCRYPTION_BLOCKSIZE. This value
1118:                    // is made persistent by storing it in service.properties
1119:                    // To connect to an existing database, retrieve the value and use it for
1120:                    // appropriate padding.
1121:                    // The  default value of encryption block size is 8,
1122:                    // to allow for downgrade issues
1123:                    // Before support for AES (beetle6023), default encryption block size supported
1124:                    // was 8
1125:
1126:                    if (setupEncryption) {
1127:                        encryptionBlockSize = encryptionEngine
1128:                                .getEncryptionBlockSize();
1129:                        // in case of database create, store the encryption block
1130:                        // size. Incase of reconfiguring the existing datbase, this
1131:                        // will be saved after encrypting the exisiting data. 
1132:                        if (create)
1133:                            properties.put(
1134:                                    RawStoreFactory.ENCRYPTION_BLOCKSIZE,
1135:                                    String.valueOf(encryptionBlockSize));
1136:                    } else {
1137:                        if (properties
1138:                                .getProperty(RawStoreFactory.ENCRYPTION_BLOCKSIZE) != null)
1139:                            encryptionBlockSize = Integer
1140:                                    .parseInt(properties
1141:                                            .getProperty(RawStoreFactory.ENCRYPTION_BLOCKSIZE));
1142:                        else
1143:                            encryptionBlockSize = encryptionEngine
1144:                                    .getEncryptionBlockSize();
1145:                    }
1146:
1147:                    decryptionEngine = currentCipherFactory
1148:                            .createNewCipher(CipherFactory.DECRYPT);
1149:
1150:                    random = currentCipherFactory.getSecureRandom();
1151:
1152:                    if (encryptDatabase) {
1153:
1154:                        if (reEncrypt) {
1155:                            // create new cipher factory with the new encrytpion
1156:                            // properties specified by the user. This cipher factory
1157:                            // is used to create the new encryption/decryption
1158:                            // engines to reencrypt the database with the new
1159:                            // encryption keys. 
1160:                            newCipherFactory = cb.createCipherFactory(
1161:                                    setupEncryption, properties, true);
1162:                            newDecryptionEngine = newCipherFactory
1163:                                    .createNewCipher(CipherFactory.DECRYPT);
1164:                            newEncryptionEngine = newCipherFactory
1165:                                    .createNewCipher(CipherFactory.ENCRYPT);
1166:                        } else {
1167:                            // there is only one engine when configuring an 
1168:                            // unencrypted database for encryption 
1169:                            newDecryptionEngine = decryptionEngine;
1170:                            newEncryptionEngine = encryptionEngine;
1171:
1172:                        }
1173:                    }
1174:
1175:                    // save the encryption properties if encryption is enabled 
1176:                    // at database creation time. 
1177:                    if (create)
1178:                        currentCipherFactory.saveProperties(properties);
1179:                }
1180:            }
1181:
1182:            /**
1183:            	Encrypt cleartext into ciphertext.
1184:
1185:            	@see CipherProvider#encrypt
1186:
1187:            	@exception StandardException Standard Cloudscape Error Policy
1188:             */
1189:            public int encrypt(byte[] cleartext, int offset, int length,
1190:                    byte[] ciphertext, int outputOffset, boolean newEngine)
1191:                    throws StandardException {
1192:                if ((databaseEncrypted == false && encryptDatabase == false)
1193:                        || (encryptionEngine == null && newEncryptionEngine == null)) {
1194:                    throw StandardException
1195:                            .newException(SQLState.STORE_FEATURE_NOT_IMPLEMENTED);
1196:                }
1197:
1198:                counter_encrypt++;
1199:
1200:                if (newEngine) {
1201:                    return newEncryptionEngine.encrypt(cleartext, offset,
1202:                            length, ciphertext, outputOffset);
1203:                } else {
1204:                    return encryptionEngine.encrypt(cleartext, offset, length,
1205:                            ciphertext, outputOffset);
1206:                }
1207:            }
1208:
1209:            /**
1210:            	Decrypt cleartext from ciphertext.
1211:
1212:            	@see CipherProvider#decrypt
1213:
1214:            	@exception StandardException Standard Cloudscape Error Policy
1215:             */
1216:            public int decrypt(byte[] ciphertext, int offset, int length,
1217:                    byte[] cleartext, int outputOffset)
1218:                    throws StandardException {
1219:                if (databaseEncrypted == false || decryptionEngine == null) {
1220:                    throw StandardException
1221:                            .newException(SQLState.STORE_FEATURE_NOT_IMPLEMENTED);
1222:                }
1223:
1224:                counter_decrypt++;
1225:                return decryptionEngine.decrypt(ciphertext, offset, length,
1226:                        cleartext, outputOffset);
1227:            }
1228:
1229:            /**
1230:            	Returns the encryption block size used by the algorithm at time of
1231:            	creation of an encrypted database
1232:             */
1233:            public int getEncryptionBlockSize() {
1234:                return encryptionBlockSize;
1235:            }
1236:
1237:            public int random() {
1238:                // don't synchronize it, the more random the better.
1239:                return databaseEncrypted ? random.nextInt() : 0;
1240:            }
1241:
1242:            public Serializable changeBootPassword(Properties properties,
1243:                    Serializable changePassword) throws StandardException {
1244:                if (isReadOnly())
1245:                    throw StandardException
1246:                            .newException(SQLState.DATABASE_READ_ONLY);
1247:
1248:                if (!databaseEncrypted)
1249:                    throw StandardException
1250:                            .newException(SQLState.DATABASE_NOT_ENCRYPTED);
1251:
1252:                if (changePassword == null)
1253:                    throw StandardException
1254:                            .newException(SQLState.NULL_BOOT_PASSWORD);
1255:
1256:                if (!(changePassword instanceof  String))
1257:                    throw StandardException
1258:                            .newException(SQLState.NON_STRING_BP);
1259:
1260:                // the new bootPassword is expected to be of the form
1261:                // oldkey , newkey.
1262:                String changeString = (String) changePassword;
1263:
1264:                return currentCipherFactory.changeBootPassword(
1265:                        (String) changePassword, properties, encryptionEngine);
1266:
1267:            }
1268:
1269:            /**
1270:             * (re) encryption testing debug flags that are used to 
1271:             * simulate error/crash conditions for testing purposes.
1272:             * When any one of the following flags are set to true
1273:             * in the debug mode, re-encryption will fail at that point.
1274:             */
1275:
1276:            public static final String TEST_REENCRYPT_CRASH_BEFORE_COMMT = SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_BEFORE_COMMT"
1277:                    : null;
1278:            public static final String TEST_REENCRYPT_CRASH_AFTER_COMMT = SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_AFTER_COMMT"
1279:                    : null;
1280:            public static final String TEST_REENCRYPT_CRASH_AFTER_SWITCH_TO_NEWKEY = SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_AFTER_SWITCH_TO_NEWKEY"
1281:                    : null;
1282:            public static final String TEST_REENCRYPT_CRASH_AFTER_CHECKPOINT = SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_AFTER_CHECKPOINT"
1283:                    : null;
1284:            public static final String TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_LOGFILE_DELETE = SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_LOGFILE_DELETE"
1285:                    : null;
1286:            public static final String TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_REVERTING_KEY = SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_REVERTING_KEY"
1287:                    : null;
1288:            public static final String TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP = SanityManager.DEBUG ? "TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP"
1289:                    : null;
1290:
1291:            /** 
1292:             * when the input debug flag is set, an expception 
1293:             * is throw when run in the debug mode.
1294:             */
1295:            private void crashOnDebugFlag(String debugFlag, boolean reEncrypt)
1296:                    throws StandardException {
1297:                if (SanityManager.DEBUG) {
1298:                    // if the test debug flag is set, throw an 
1299:                    // exception to simulate error cases.
1300:                    if (SanityManager.DEBUG_ON(debugFlag)) {
1301:                        StandardException se = StandardException
1302:                                .newException(
1303:                                        (reEncrypt ? SQLState.DATABASE_REENCRYPTION_FAILED
1304:                                                : SQLState.DATABASE_ENCRYPTION_FAILED),
1305:                                        debugFlag);
1306:                        markCorrupt(se);
1307:                        throw se;
1308:                    }
1309:                }
1310:            }
1311:
1312:            /*
1313:             * Configure the database for encryption, with the  specified 
1314:             * encryption  properties.
1315:             *
1316:             * Basic idea is to encrypt all the containers with new password/key 
1317:             * specified by the user and keep old versions of the data to 
1318:             * rollback the database to the state before the configuration of database 
1319:             * with new encryption attributes. Users can configure the database with 
1320:             * new encryption  attributes at boot time only; advantage of this approach
1321:             * is that there will not be any concurrency issues to handle because
1322:             * no users will be modifying the data. 
1323:             *
1324:             * First step is to encrypt the existing data with new encryption 
1325:             * attributes  and then update the encryption properties for 
1326:             * the database. Configuring  an un-encrypted database for 
1327:             * encryption problem is a minor variation of  re-encrypting an 
1328:             * encrypted database with new encryption key. The database 
1329:             * reconfiguration with new encryption attributes is done under one
1330:             * transaction, if there is a crash/error before it is committed, 
1331:             * then it  is rolled back and the database will be brought back to the
1332:             * state it was before the encryption.  
1333:             *
1334:             * One trickey case in (re) encrypion of database is 
1335:             * unlike standard protocol transaction  commit means all done, 
1336:             * database (re) encryption process has to perform a checkpoint
1337:             *  with a newly generated key then only database  (re) encrption 
1338:             * is complete, Otherwise the problem  is recovery has to deal 
1339:             * with transaction log that is encrypted with old encryption key and 
1340:             * the new encryption key. This probelm is avoided  writing COMMIT
1341:             * and new  CHECKPOINT log record  to a new log file and encrypt the 
1342:             * with a new key, if there is  crash before checkpoint records 
1343:             * are updated , then on next boot the log file after the checkpoint 
1344:             * is deleted before reovery,  which will be the one that is  
1345:             * written with new encryption key and also contains COMMIT record, 
1346:             * so the COMMIT record is also gone when  log file is deleted. 
1347:             * Recovery will not see the commit , so it will  rollback the (re)
1348:             * encryption and revert all the containers to the 
1349:             * original versions. 
1350:             * 
1351:             * Old container versions are deleted only when the check point 
1352:             * with new encryption key is successful, not on post-commit. 
1353:             *
1354:             * @param properties  properties related to this database.
1355:             * @exception StandardException Standard Derby Error Policy
1356:             */
1357:            public void configureDatabaseForEncryption(Properties properties,
1358:                    CipherFactory newCipherFactory) throws StandardException {
1359:
1360:                boolean reEncrypt = (databaseEncrypted && encryptDatabase);
1361:
1362:                // check if the database can be encrypted.
1363:                canEncryptDatabase(reEncrypt);
1364:
1365:                boolean externalKeyEncryption = false;
1366:                if (properties.getProperty(Attribute.CRYPTO_EXTERNAL_KEY) != null) {
1367:                    externalKeyEncryption = true;
1368:                }
1369:
1370:                // check point the datase, so that encryption does not have
1371:                // to encrypt the existing transactions logs. 
1372:
1373:                logFactory.checkpoint(this , dataFactory, xactFactory, true);
1374:
1375:                // start a transaction that is to be used for encryting the database
1376:                RawTransaction transaction = xactFactory.startTransaction(this ,
1377:                        ContextService.getFactory().getCurrentContextManager(),
1378:                        AccessFactoryGlobals.USER_TRANS_NAME);
1379:
1380:                try {
1381:
1382:                    dataFactory.encryptAllContainers(transaction);
1383:
1384:                    // all the containers are (re) encrypted, now mark the database as
1385:                    // encrypted if a plain database is getting configured for encryption
1386:                    // or update the encryption the properties, in the 
1387:                    // service.properties ..etc.
1388:
1389:                    if (SanityManager.DEBUG) {
1390:                        crashOnDebugFlag(TEST_REENCRYPT_CRASH_BEFORE_COMMT,
1391:                                reEncrypt);
1392:                    }
1393:
1394:                    // check if the checkpoint is currently in the last log file, 
1395:                    // otherwise force a checkpoint and then do a log switch, 
1396:                    // after setting up a new encryption key
1397:                    if (!logFactory.isCheckpointInLastLogFile()) {
1398:                        // perfrom a checkpoint, this is a reference checkpoint 
1399:                        // to find if the re(encryption) is complete. 
1400:                        logFactory.checkpoint(this , dataFactory, xactFactory,
1401:                                true);
1402:                    }
1403:
1404:                    encryptDatabase = false;
1405:
1406:                    // let the log factory know that database is 
1407:                    // (re) encrypted and ask it to flush the log, 
1408:                    // before enabling encryption of the log with 
1409:                    // the new key.
1410:                    logFactory.setDatabaseEncrypted(true);
1411:
1412:                    // let the log factory and data factory know that 
1413:                    // database is encrypted.
1414:                    if (!reEncrypt) {
1415:                        // mark in the raw store that the database is 
1416:                        // encrypted. 
1417:                        databaseEncrypted = true;
1418:                        dataFactory.setDatabaseEncrypted();
1419:                    } else {
1420:                        // switch the encryption/decryption engine to the new ones.
1421:                        decryptionEngine = newDecryptionEngine;
1422:                        encryptionEngine = newEncryptionEngine;
1423:                        currentCipherFactory = newCipherFactory;
1424:                    }
1425:
1426:                    // make the log factory ready to encrypt
1427:                    // the transaction log with the new encryption 
1428:                    // key by switching to a new log file. 
1429:                    // If re-encryption is aborted for any reason, 
1430:                    // this new log file will be deleted, during
1431:                    // recovery.
1432:
1433:                    logFactory.startNewLogFile();
1434:
1435:                    // mark that re-encryption is in progress in the 
1436:                    // service.properties, so that (re) encryption 
1437:                    // changes that can not be undone using the transaction 
1438:                    // log can be un-done before recovery starts.
1439:                    // (like the changes to service.properties and 
1440:                    // any log files the can not be understood by the
1441:                    // old encryption key), incase engine crashes
1442:                    // after this point. 
1443:
1444:                    // if the crash occurs before this point, recovery
1445:                    // will rollback the changes using the transaction 
1446:                    // log.
1447:
1448:                    properties
1449:                            .put(
1450:                                    RawStoreFactory.DB_ENCRYPTION_STATUS,
1451:                                    String
1452:                                            .valueOf(RawStoreFactory.DB_ENCRYPTION_IN_PROGRESS));
1453:
1454:                    if (reEncrypt) {
1455:                        // incase re-encryption, save the old 
1456:                        // encryption related properties, before
1457:                        // doing updates with new values.
1458:
1459:                        if (externalKeyEncryption) {
1460:                            // save the current copy of verify key file.
1461:                            StorageFile verifyKeyFile = storageFactory
1462:                                    .newStorageFile(Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE);
1463:                            StorageFile oldVerifyKeyFile = storageFactory
1464:                                    .newStorageFile(RawStoreFactory.CRYPTO_OLD_EXTERNAL_KEY_VERIFY_FILE);
1465:
1466:                            if (!privCopyFile(verifyKeyFile, oldVerifyKeyFile))
1467:                                throw StandardException.newException(
1468:                                        SQLState.RAWSTORE_ERROR_COPYING_FILE,
1469:                                        verifyKeyFile, oldVerifyKeyFile);
1470:
1471:                            // update the verify key file with the new key info.
1472:                            currentCipherFactory.verifyKey(reEncrypt,
1473:                                    storageFactory, properties);
1474:                        } else {
1475:                            // save the current generated encryption key 
1476:                            String keyString = properties
1477:                                    .getProperty(RawStoreFactory.ENCRYPTED_KEY);
1478:                            if (keyString != null)
1479:                                properties.put(
1480:                                        RawStoreFactory.OLD_ENCRYPTED_KEY,
1481:                                        keyString);
1482:                        }
1483:                    } else {
1484:                        // save the encryption block size;
1485:                        properties.put(RawStoreFactory.ENCRYPTION_BLOCKSIZE,
1486:                                String.valueOf(encryptionBlockSize));
1487:                    }
1488:
1489:                    // save the new encryption properties into service.properties
1490:                    currentCipherFactory.saveProperties(properties);
1491:
1492:                    if (SanityManager.DEBUG) {
1493:                        crashOnDebugFlag(
1494:                                TEST_REENCRYPT_CRASH_AFTER_SWITCH_TO_NEWKEY,
1495:                                reEncrypt);
1496:                    }
1497:
1498:                    // commit the transaction that is used to 
1499:                    // (re) encrypt the database. Note that 
1500:                    // this will be logged with newly generated 
1501:                    // encryption key in the new log file created 
1502:                    // above.
1503:                    transaction.commit();
1504:
1505:                    if (SanityManager.DEBUG) {
1506:                        crashOnDebugFlag(TEST_REENCRYPT_CRASH_AFTER_COMMT,
1507:                                reEncrypt);
1508:                    }
1509:
1510:                    // force the checkpoint with new encryption key.
1511:                    logFactory.checkpoint(this , dataFactory, xactFactory, true);
1512:
1513:                    if (SanityManager.DEBUG) {
1514:                        crashOnDebugFlag(TEST_REENCRYPT_CRASH_AFTER_CHECKPOINT,
1515:                                reEncrypt);
1516:                    }
1517:
1518:                    // once the checkpont makes it to the log, re-encrption 
1519:                    // is complete. only cleanup is remaining ; update the 
1520:                    // re-encryption status flag to cleanup. 
1521:                    properties.put(RawStoreFactory.DB_ENCRYPTION_STATUS, String
1522:                            .valueOf(RawStoreFactory.DB_ENCRYPTION_IN_CLEANUP));
1523:
1524:                    // database is (re)encrypted successfuly, 
1525:                    // remove the old version of the container files.
1526:                    dataFactory.removeOldVersionOfContainers(false);
1527:
1528:                    if (reEncrypt) {
1529:                        if (externalKeyEncryption) {
1530:                            // remove the saved copy of the verify.key file
1531:                            StorageFile oldVerifyKeyFile = storageFactory
1532:                                    .newStorageFile(RawStoreFactory.CRYPTO_OLD_EXTERNAL_KEY_VERIFY_FILE);
1533:                            if (!privDelete(oldVerifyKeyFile))
1534:                                throw StandardException.newException(
1535:                                        SQLState.UNABLE_TO_DELETE_FILE,
1536:                                        oldVerifyKeyFile);
1537:                        } else {
1538:                            // remove the old encryption key property.
1539:                            properties
1540:                                    .remove(RawStoreFactory.OLD_ENCRYPTED_KEY);
1541:                        }
1542:                    }
1543:
1544:                    // (re) encrypion is done,  remove the (re) 
1545:                    // encryption status property. 
1546:
1547:                    properties.remove(RawStoreFactory.DB_ENCRYPTION_STATUS);
1548:
1549:                    // close the transaction. 
1550:                    transaction.close();
1551:
1552:                } catch (StandardException se) {
1553:
1554:                    throw StandardException.newException(
1555:                            (reEncrypt ? SQLState.DATABASE_REENCRYPTION_FAILED
1556:                                    : SQLState.DATABASE_ENCRYPTION_FAILED), se,
1557:                            se.getMessage());
1558:                } finally {
1559:                    // clear the new encryption engines.
1560:                    newDecryptionEngine = null;
1561:                    newEncryptionEngine = null;
1562:                }
1563:            }
1564:
1565:            /**
1566:             * Engine might have crashed during encryption of un-encrypted datbase
1567:             * or while re-encryptin an already encrypted database with a new key
1568:             * after all the containers or (re) encrypted. If crash has occured
1569:             * before all containers are encrypted, recovery wil un-do re-encryption
1570:             * using the transaction log, nothing to be done here.
1571:             *
1572:             * If crash has occured after database encryption status flag 
1573:             * (RawStoreFactory.DB_ENCRYPTION_STATUS) is set, this method 
1574:             * will do any cleanup necessary for the recovery to correctly
1575:             * perform the rollback if required. 
1576:             *
1577:             *
1578:             *
1579:             * @param properties  properties related to this database.
1580:             * @exception StandardException Standard Derby Error Policy
1581:             *
1582:             */
1583:            public void handleIncompleteDatabaseEncryption(Properties properties)
1584:                    throws StandardException {
1585:                // find what was the encryption status before database crashed. 
1586:                int dbEncryptionStatus = 0;
1587:                String dbEncryptionStatusStr = properties
1588:                        .getProperty(RawStoreFactory.DB_ENCRYPTION_STATUS);
1589:                if (dbEncryptionStatusStr != null)
1590:                    dbEncryptionStatus = Integer
1591:                            .parseInt(dbEncryptionStatusStr);
1592:
1593:                boolean reEncryption = false;
1594:                // check if engine crashed when (re) encryption was in progress.
1595:                if (dbEncryptionStatus == RawStoreFactory.DB_ENCRYPTION_IN_PROGRESS) {
1596:
1597:                    // check if it crashed immediately after completion or
1598:                    // before. if the checkpoint is in the last log file 
1599:                    // encrypted with new encryption key, it is as good 
1600:                    // as complete. In this case just cleanup any uncleared
1601:                    // flags and mark that database is encrypted.
1602:
1603:                    if (logFactory.isCheckpointInLastLogFile()) {
1604:                        // database (re)encryption was successful, only 
1605:                        // cleanup is remaining. change the status to cleanup. 
1606:                        dbEncryptionStatus = RawStoreFactory.DB_ENCRYPTION_IN_CLEANUP;
1607:                    } else {
1608:
1609:                        // crash occured before re-encrytion was completed. 
1610:                        // update the db re-encryption status and write to 
1611:                        // the service.properties that re-encryption 
1612:                        // needs to be undone. The reason this status need 
1613:                        // to be made persistent, it will help to correctly 
1614:                        // handle a crash in this routine after the log file 
1615:                        // encrypted with new key is deleted. If this flag
1616:                        // is not set, on next reboot, above check 
1617:                        // will find checkpoint in the last log file and 
1618:                        // incorrecly assume (re) encryption is
1619:                        // successful.
1620:
1621:                        dbEncryptionStatus = RawStoreFactory.DB_ENCRYPTION_IN_UNDO;
1622:                        properties.put(RawStoreFactory.DB_ENCRYPTION_STATUS,
1623:                                String.valueOf(dbEncryptionStatus));
1624:                    }
1625:                }
1626:
1627:                if (dbEncryptionStatus == RawStoreFactory.DB_ENCRYPTION_IN_UNDO) {
1628:                    // delete the log file after the log file that has the checkpoint , 
1629:                    // it has the data encrypted with the new key, including the commit
1630:                    // record for the transaction that was used to (re)encrypt 
1631:                    // the database. By Deleting the log file, we are forcing the
1632:                    // recovery to rollback the (re)encryption of the database. 
1633:
1634:                    logFactory.deleteLogFileAfterCheckpointLogFile();
1635:
1636:                    if (SanityManager.DEBUG) {
1637:                        crashOnDebugFlag(
1638:                                TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_LOGFILE_DELETE,
1639:                                reEncryption);
1640:                    }
1641:
1642:                    // Note : If a crash occurs at this point, then on reboot 
1643:                    // it will again be in the DB_ENRYPTION_IN__UNDO state, 
1644:                    // there will not be a file after the checkpoint log file, 
1645:                    // so no file will be deleted. 
1646:
1647:                    // check if this is a external key encryption and 
1648:                    // if it replace the current verify key file with 
1649:                    // the old copy. 
1650:
1651:                    StorageFile verifyKeyFile = storageFactory
1652:                            .newStorageFile(Attribute.CRYPTO_EXTERNAL_KEY_VERIFY_FILE);
1653:
1654:                    if (privExists(verifyKeyFile)) {
1655:                        StorageFile oldVerifyKeyFile = storageFactory
1656:                                .newStorageFile(RawStoreFactory.CRYPTO_OLD_EXTERNAL_KEY_VERIFY_FILE);
1657:
1658:                        if (privExists(oldVerifyKeyFile)) {
1659:                            if (!privCopyFile(oldVerifyKeyFile, verifyKeyFile))
1660:                                throw StandardException.newException(
1661:                                        SQLState.RAWSTORE_ERROR_COPYING_FILE,
1662:                                        oldVerifyKeyFile, verifyKeyFile);
1663:
1664:                            // only incase of re-encryption there should
1665:                            // be old verify key file. 
1666:                            reEncryption = true;
1667:                        } else {
1668:                            // remove the verify key file. 
1669:                            if (!privDelete(verifyKeyFile))
1670:                                throw StandardException.newException(
1671:                                        SQLState.UNABLE_TO_DELETE_FILE,
1672:                                        verifyKeyFile);
1673:                        }
1674:
1675:                    } else {
1676:                        // database enrypted with boot password. 
1677:
1678:                        // replace the current encryption key with the old key
1679:                        // in the service.properties file. 
1680:                        // retreive the old encryption key 
1681:
1682:                        String OldKeyString = properties
1683:                                .getProperty(RawStoreFactory.OLD_ENCRYPTED_KEY);
1684:
1685:                        if (OldKeyString != null) {
1686:                            // set the current encrypted key to the old one. 
1687:                            properties.put(RawStoreFactory.ENCRYPTED_KEY,
1688:                                    OldKeyString);
1689:
1690:                            // only incase of re-encryption there should
1691:                            // be old encryted key . 
1692:                            reEncryption = true;
1693:                        }
1694:                    }
1695:
1696:                    if (!reEncryption) {
1697:                        // crash occured when database was getting reconfigured 
1698:                        // for encryption , all encryption properties should be 
1699:                        // removed from service.properties
1700:
1701:                        // common props for external key or password.
1702:                        properties.remove(Attribute.DATA_ENCRYPTION);
1703:                        properties
1704:                                .remove(RawStoreFactory.LOG_ENCRYPT_ALGORITHM_VERSION);
1705:                        properties
1706:                                .remove(RawStoreFactory.DATA_ENCRYPT_ALGORITHM_VERSION);
1707:                        properties.remove(RawStoreFactory.ENCRYPTION_BLOCKSIZE);
1708:
1709:                        // properties specific to password based encryption.
1710:                        properties.remove(Attribute.CRYPTO_KEY_LENGTH);
1711:                        properties.remove(Attribute.CRYPTO_PROVIDER);
1712:                        properties.remove(Attribute.CRYPTO_ALGORITHM);
1713:                        properties.remove(RawStoreFactory.ENCRYPTED_KEY);
1714:
1715:                    }
1716:
1717:                    if (SanityManager.DEBUG) {
1718:                        crashOnDebugFlag(
1719:                                TEST_REENCRYPT_CRASH_AFTER_RECOVERY_UNDO_REVERTING_KEY,
1720:                                reEncryption);
1721:                    }
1722:
1723:                } // end of UNDO
1724:
1725:                if (dbEncryptionStatus == RawStoreFactory.DB_ENCRYPTION_IN_CLEANUP) {
1726:                    // remove all the old versions of the  containers. 
1727:                    dataFactory.removeOldVersionOfContainers(true);
1728:                }
1729:
1730:                if (SanityManager.DEBUG) {
1731:                    crashOnDebugFlag(
1732:                            TEST_REENCRYPT_CRASH_BEFORE_RECOVERY_FINAL_CLEANUP,
1733:                            reEncryption);
1734:                }
1735:
1736:                // either the (re) encryption was complete , 
1737:                // or undone (except for rollback that needs to be 
1738:                // done by the recovery). Remove re-encryption specific
1739:                // flags from the service.properties and old copy 
1740:                // of the verify key file.
1741:
1742:                // delete the old verify key file , if it exists. 
1743:                StorageFile oldVerifyKeyFile = storageFactory
1744:                        .newStorageFile(RawStoreFactory.CRYPTO_OLD_EXTERNAL_KEY_VERIFY_FILE);
1745:                if (privExists(oldVerifyKeyFile)) {
1746:                    if (!privDelete(oldVerifyKeyFile))
1747:                        throw StandardException.newException(
1748:                                SQLState.UNABLE_TO_DELETE_FILE,
1749:                                oldVerifyKeyFile);
1750:                } else {
1751:                    // remove the old encryption key property.
1752:                    properties.remove(RawStoreFactory.OLD_ENCRYPTED_KEY);
1753:                }
1754:
1755:                // remove the re-encryptin status flag. 
1756:                properties.remove(RawStoreFactory.DB_ENCRYPTION_STATUS);
1757:            }
1758:
1759:            /**
1760:             * checks if the database is in the right state to (re)encrypt it.
1761:             *
1762:             * @param  reEncrypt true if the database getting encrypted 
1763:             *                   with new password/key.
1764:             * @exception  StandardException  
1765:             *             if there is global transaction in the prepared state or
1766:             *             if the database is not at the version 10.2 or above, this
1767:             *             feature is not supported or  
1768:             *             if the log is archived for the database.
1769:             */
1770:            private void canEncryptDatabase(boolean reEncrypt)
1771:                    throws StandardException {
1772:
1773:                String feature = (reEncrypt ? "newBootPassword/newEncryptionKey attribute"
1774:                        : "dataEncryption attribute on an existing database");
1775:
1776:                // check if the database version is at 10.2 or above.
1777:                // encrytpion or re-encryption of the database 
1778:                // is supported  only in version 10.2 or above. 
1779:                logFactory.checkVersion(
1780:                        RawStoreFactory.DERBY_STORE_MAJOR_VERSION_10,
1781:                        RawStoreFactory.DERBY_STORE_MINOR_VERSION_2, feature);
1782:
1783:                // database can not be (re)encrypted if there 
1784:                // are any global transactions in the prepared state 
1785:                // after the recovery. The reason for this restriction 
1786:                // is that any transaction log before the encryption can not 
1787:                // be read once database is reconfigure with new encryption 
1788:                // key.
1789:                if (xactFactory.hasPreparedXact()) {
1790:                    if (reEncrypt)
1791:                        throw StandardException
1792:                                .newException(SQLState.REENCRYPTION_PREPARED_XACT_EXIST);
1793:                    else
1794:                        throw StandardException
1795:                                .newException(SQLState.ENCRYPTION_PREPARED_XACT_EXIST);
1796:                }
1797:
1798:                // check if the database has the log archived. 
1799:                // database can not be congured of encryption or
1800:                // or re-encrypt it with a new key when the database 
1801:                // log is being archived. The reason for this restriction is 
1802:                // it will create a scenarion where users will 
1803:                // have some logs encrypted with new key and some with old key 
1804:                // when rollforward recovery is performed. 
1805:
1806:                if (logFactory.logArchived()) {
1807:                    if (reEncrypt)
1808:                        throw StandardException
1809:                                .newException(SQLState.CANNOT_REENCRYPT_LOG_ARCHIVED_DATABASE);
1810:                    else
1811:                        throw StandardException
1812:                                .newException(SQLState.CANNOT_ENCRYPT_LOG_ARCHIVED_DATABASE);
1813:
1814:                }
1815:            }
1816:
1817:            /*
1818:             **
1819:             */
1820:
1821:            public StandardException markCorrupt(StandardException originalError) {
1822:
1823:                logFactory.markCorrupt(originalError);
1824:                dataFactory.markCorrupt(originalError);
1825:                xactFactory.markCorrupt(originalError);
1826:
1827:                return originalError;
1828:            }
1829:
1830:            /*
1831:             * class specific methods
1832:             */
1833:
1834:            /* subclass can override this method to load different submodules */
1835:            public String getTransactionFactoryModule() {
1836:                return TransactionFactory.MODULE;
1837:            }
1838:
1839:            public String getDataFactoryModule() {
1840:                return DataFactory.MODULE;
1841:            }
1842:
1843:            public String getLogFactoryModule() {
1844:                return LogFactory.MODULE;
1845:            }
1846:
1847:            private void logHistory(OutputStreamWriter historyFile, String msg)
1848:                    throws IOException {
1849:                Date d = new Date();
1850:                historyFile.write(d.toString() + ":" + msg + "\n");
1851:                historyFile.flush();
1852:            }
1853:
1854:            /*
1855:             * Get the file path. If the canonical path can be obtained then return the 
1856:             * canonical path, otherwise just return the abstract path. Typically if
1857:             * there are no permission to read user.dir when  running under security
1858:             * manager canonical path can not be obtained.
1859:             *
1860:             * This method is used to a write path name to error/status log file, where it
1861:             * would be nice to print full paths but not esstential that the user 
1862:             * grant permissions to read user.dir property.
1863:             */
1864:            private String getFilePath(StorageFile file) {
1865:                String path = privGetCanonicalPath(file);
1866:                if (path != null) {
1867:                    return path;
1868:                } else {
1869:                    //can not get the canoncal path, 
1870:                    // return the abstract path
1871:                    return file.getPath();
1872:                }
1873:            }
1874:
1875:            /*
1876:             * Get the file path.  If the canonical path can be obtained then return the 
1877:             * canonical path, otherwise just return the abstract path. Typically if
1878:             * there are no permission to read user.dir when  running under security
1879:             * manager canonical path can not be obtained.
1880:             *
1881:             * This method is used to a write a file path name to error/status log file, 
1882:             * where it would be nice to print full paths but not esstential that the user
1883:             * grant permissions to read user.dir property.
1884:             *
1885:             */
1886:            private String getFilePath(File file) {
1887:                String path = privGetCanonicalPath(file);
1888:                if (path != null) {
1889:                    return path;
1890:                } else {
1891:                    // can not get the canoncal path, 
1892:                    // return the abstract path
1893:                    return file.getPath();
1894:                }
1895:            }
1896:
1897:            protected boolean privCopyDirectory(StorageFile from, File to) {
1898:                return privCopyDirectory(from, to, (byte[]) null,
1899:                        (String[]) null, true);
1900:            }
1901:
1902:            protected boolean privCopyDirectory(File from, StorageFile to) {
1903:                return privCopyDirectory(from, to, (byte[]) null,
1904:                        (String[]) null);
1905:            }
1906:
1907:            /**
1908:             * Return an id which can be used to create a container.
1909:             * <p>
1910:             * Return an id number with is greater than any existing container
1911:             * in the current database.  Caller will use this to allocate future
1912:             * container numbers - most likely caching the value and then incrementing
1913:             * it as it is used.
1914:             * <p>
1915:             *
1916:             * @return The an id which can be used to create a container.
1917:             *
1918:             * @exception  StandardException  Standard exception policy.
1919:             **/
1920:            public long getMaxContainerId() throws StandardException {
1921:                return (dataFactory.getMaxContainerId());
1922:            }
1923:
1924:            /*
1925:                These methods require Priv Blocks when run under a security manager.
1926:             */
1927:
1928:            private synchronized OutputStreamWriter privFileWriter(
1929:                    StorageFile fileName, boolean append) throws IOException {
1930:                actionCode = FILE_WRITER_ACTION;
1931:                actionStorageFile = fileName;
1932:                actionAppend = append;
1933:                try {
1934:                    return (OutputStreamWriter) java.security.AccessController
1935:                            .doPrivileged(this );
1936:                } catch (java.security.PrivilegedActionException pae) {
1937:                    throw (IOException) pae.getException();
1938:                } finally {
1939:                    actionStorageFile = null;
1940:                }
1941:            }
1942:
1943:            private synchronized boolean privExists(File file) {
1944:                actionCode = REGULAR_FILE_EXISTS_ACTION;
1945:                actionRegularFile = file;
1946:
1947:                try {
1948:                    Object ret = AccessController.doPrivileged(this );
1949:                    return ((Boolean) ret).booleanValue();
1950:                } catch (PrivilegedActionException pae) {
1951:                    return false;
1952:                } // does not throw an exception
1953:                finally {
1954:                    actionRegularFile = null;
1955:                }
1956:            }
1957:
1958:            private synchronized boolean privExists(final StorageFile file) {
1959:                actionCode = STORAGE_FILE_EXISTS_ACTION;
1960:                actionStorageFile = file;
1961:
1962:                try {
1963:                    Object ret = AccessController.doPrivileged(this );
1964:                    return ((Boolean) ret).booleanValue();
1965:                } catch (PrivilegedActionException pae) {
1966:                    return false;
1967:                } // does not throw an exception
1968:                finally {
1969:                    actionStorageFile = null;
1970:                }
1971:            }
1972:
1973:            private synchronized boolean privDelete(File file) {
1974:                actionCode = REGULAR_FILE_DELETE_ACTION;
1975:                actionRegularFile = file;
1976:
1977:                try {
1978:                    Object ret = AccessController.doPrivileged(this );
1979:                    return ((Boolean) ret).booleanValue();
1980:                } catch (PrivilegedActionException pae) {
1981:                    return false;
1982:                } // does not throw an exception
1983:                finally {
1984:                    actionRegularFile = null;
1985:                }
1986:            }
1987:
1988:            private synchronized boolean privDelete(StorageFile file) {
1989:                actionCode = STORAGE_FILE_DELETE_ACTION;
1990:                actionStorageFile = file;
1991:
1992:                try {
1993:                    Object ret = AccessController.doPrivileged(this );
1994:                    return ((Boolean) ret).booleanValue();
1995:                } catch (PrivilegedActionException pae) {
1996:                    return false;
1997:                } // does not throw an exception
1998:                finally {
1999:                    actionStorageFile = null;
2000:                }
2001:            }
2002:
2003:            private synchronized boolean privMkdirs(File file) {
2004:                actionCode = REGULAR_FILE_MKDIRS_ACTION;
2005:                actionRegularFile = file;
2006:
2007:                try {
2008:                    Object ret = AccessController.doPrivileged(this );
2009:                    return ((Boolean) ret).booleanValue();
2010:                } catch (PrivilegedActionException pae) {
2011:                    return false;
2012:                } // does not throw an exception
2013:                finally {
2014:                    actionRegularFile = null;
2015:                }
2016:            }
2017:
2018:            private synchronized boolean privIsDirectory(File file) {
2019:                actionCode = REGULAR_FILE_IS_DIRECTORY_ACTION;
2020:                actionRegularFile = file;
2021:
2022:                try {
2023:                    Object ret = AccessController.doPrivileged(this );
2024:                    return ((Boolean) ret).booleanValue();
2025:                } catch (PrivilegedActionException pae) {
2026:                    return false;
2027:                } // does not throw an exception
2028:                finally {
2029:                    actionRegularFile = null;
2030:                }
2031:            }
2032:
2033:            private synchronized boolean privRemoveDirectory(File file) {
2034:                actionCode = REGULAR_FILE_REMOVE_DIRECTORY_ACTION;
2035:                actionRegularFile = file;
2036:
2037:                try {
2038:                    Object ret = AccessController.doPrivileged(this );
2039:                    return ((Boolean) ret).booleanValue();
2040:                } catch (PrivilegedActionException pae) {
2041:                    return false;
2042:                } // does not throw an exception
2043:                finally {
2044:                    actionRegularFile = null;
2045:                }
2046:            }
2047:
2048:            private synchronized boolean privRenameTo(File file1, File file2) {
2049:                actionCode = REGULAR_FILE_RENAME_TO_ACTION;
2050:                actionRegularFile = file1;
2051:                actionRegularFile2 = file2;
2052:
2053:                try {
2054:                    Object ret = AccessController.doPrivileged(this );
2055:                    return ((Boolean) ret).booleanValue();
2056:                } catch (PrivilegedActionException pae) {
2057:                    return false;
2058:                } // does not throw an exception
2059:                finally {
2060:                    actionRegularFile = null;
2061:                    actionRegularFile2 = null;
2062:                }
2063:            }
2064:
2065:            private synchronized boolean privCopyDirectory(StorageFile from,
2066:                    File to, byte[] buffer, String[] filter, boolean copySubdirs) {
2067:                actionCode = COPY_STORAGE_DIRECTORY_TO_REGULAR_ACTION;
2068:                actionStorageFile = from;
2069:                actionRegularFile = to;
2070:                actionBuffer = buffer;
2071:                actionFilter = filter;
2072:                actionCopySubDirs = copySubdirs;
2073:
2074:                try {
2075:                    Object ret = AccessController.doPrivileged(this );
2076:                    return ((Boolean) ret).booleanValue();
2077:                } catch (PrivilegedActionException pae) {
2078:                    return false;
2079:                } // does not throw an exception
2080:                finally {
2081:                    actionStorageFile = null;
2082:                    actionRegularFile = null;
2083:                    actionBuffer = null;
2084:                    actionFilter = null;
2085:                }
2086:            }
2087:
2088:            private synchronized boolean privCopyDirectory(File from,
2089:                    StorageFile to, byte[] buffer, String[] filter) {
2090:                actionCode = COPY_REGULAR_DIRECTORY_TO_STORAGE_ACTION;
2091:                actionStorageFile = to;
2092:                actionRegularFile = from;
2093:                actionBuffer = buffer;
2094:                actionFilter = filter;
2095:
2096:                try {
2097:                    Object ret = AccessController.doPrivileged(this );
2098:                    return ((Boolean) ret).booleanValue();
2099:                } catch (PrivilegedActionException pae) {
2100:                    return false;
2101:                } // does not throw an exception
2102:                finally {
2103:                    actionStorageFile = null;
2104:                    actionRegularFile = null;
2105:                    actionBuffer = null;
2106:                    actionFilter = null;
2107:                }
2108:            }
2109:
2110:            private synchronized boolean privCopyFile(File from, StorageFile to) {
2111:                actionCode = COPY_REGULAR_FILE_TO_STORAGE_ACTION;
2112:                actionStorageFile = to;
2113:                actionRegularFile = from;
2114:
2115:                try {
2116:                    Object ret = AccessController.doPrivileged(this );
2117:                    return ((Boolean) ret).booleanValue();
2118:                } catch (PrivilegedActionException pae) {
2119:                    return false;
2120:                } // does not throw an exception
2121:                finally {
2122:                    actionStorageFile = null;
2123:                    actionRegularFile = null;
2124:                }
2125:            }
2126:
2127:            private synchronized boolean privCopyFile(StorageFile from, File to) {
2128:                actionCode = COPY_STORAGE_FILE_TO_REGULAR_ACTION;
2129:                actionStorageFile = from;
2130:                actionRegularFile = to;
2131:
2132:                try {
2133:                    Object ret = AccessController.doPrivileged(this );
2134:                    return ((Boolean) ret).booleanValue();
2135:                } catch (PrivilegedActionException pae) {
2136:                    return false;
2137:                } // does not throw an exception
2138:                finally {
2139:                    actionStorageFile = null;
2140:                    actionRegularFile = null;
2141:                }
2142:            }
2143:
2144:            private synchronized boolean privCopyFile(StorageFile from,
2145:                    StorageFile to) {
2146:                actionCode = COPY_STORAGE_FILE_TO_STORAGE_ACTION;
2147:                actionStorageFile = from;
2148:                actionToStorageFile = to;
2149:
2150:                try {
2151:                    Object ret = AccessController.doPrivileged(this );
2152:                    return ((Boolean) ret).booleanValue();
2153:                } catch (PrivilegedActionException pae) {
2154:                    return false;
2155:                } // does not throw an exception
2156:                finally {
2157:                    actionStorageFile = null;
2158:                    actionToStorageFile = null;
2159:                }
2160:            }
2161:
2162:            private synchronized String[] privList(final File file) {
2163:                actionCode = REGULAR_FILE_LIST_DIRECTORY_ACTION;
2164:                actionRegularFile = file;
2165:
2166:                try {
2167:                    return (String[]) AccessController.doPrivileged(this );
2168:                } catch (PrivilegedActionException pae) {
2169:                    return null;
2170:                } // does not throw an exception
2171:                finally {
2172:                    actionRegularFile = null;
2173:                }
2174:            }
2175:
2176:            private synchronized String[] privList(final StorageFile file) {
2177:                actionCode = STORAGE_FILE_LIST_DIRECTORY_ACTION;
2178:                actionStorageFile = file;
2179:
2180:                try {
2181:                    return (String[]) AccessController.doPrivileged(this );
2182:                } catch (PrivilegedActionException pae) {
2183:                    return null;
2184:                } // does not throw an exception
2185:                finally {
2186:                    actionStorageFile = null;
2187:                }
2188:            }
2189:
2190:            private synchronized String privGetCanonicalPath(
2191:                    final StorageFile file) {
2192:                actionCode = STORAGE_FILE_GET_CANONICALPATH_ACTION;
2193:                actionStorageFile = file;
2194:
2195:                try {
2196:                    return (String) AccessController.doPrivileged(this );
2197:                } catch (PrivilegedActionException pae) {
2198:                    return null;
2199:                } // does not throw an exception
2200:                catch (SecurityException se) {
2201:                    // there are no permission to get canonical path 
2202:                    // just return null.
2203:                    return null;
2204:                } finally {
2205:                    actionStorageFile = null;
2206:                }
2207:            }
2208:
2209:            private synchronized String privGetCanonicalPath(final File file) {
2210:                actionCode = REGULAR_FILE_GET_CANONICALPATH_ACTION;
2211:                actionRegularFile = file;
2212:
2213:                try {
2214:                    return (String) AccessController.doPrivileged(this );
2215:                } catch (PrivilegedActionException pae) {
2216:                    return null;
2217:                } // does not throw an exception
2218:                catch (SecurityException se) {
2219:                    // there are no permission to get canonical path 
2220:                    // just return null.
2221:                    return null;
2222:                } finally {
2223:                    actionRegularFile = null;
2224:                }
2225:            }
2226:
2227:            // PrivilegedExceptionAction method
2228:            public final Object run() throws IOException {
2229:                switch (actionCode) {
2230:                case FILE_WRITER_ACTION:
2231:                    // SECURITY PERMISSION - MP1
2232:                    return new OutputStreamWriter(actionStorageFile
2233:                            .getOutputStream(actionAppend));
2234:
2235:                case REGULAR_FILE_EXISTS_ACTION:
2236:                    return ReuseFactory.getBoolean(actionRegularFile.exists());
2237:
2238:                case STORAGE_FILE_EXISTS_ACTION:
2239:                    return ReuseFactory.getBoolean(actionStorageFile.exists());
2240:
2241:                case REGULAR_FILE_DELETE_ACTION:
2242:                    return ReuseFactory.getBoolean(actionRegularFile.delete());
2243:
2244:                case STORAGE_FILE_DELETE_ACTION:
2245:                    return ReuseFactory.getBoolean(actionStorageFile.delete());
2246:
2247:                case REGULAR_FILE_MKDIRS_ACTION:
2248:                    // SECURITY PERMISSION - OP4
2249:                    return ReuseFactory.getBoolean(actionRegularFile.mkdirs());
2250:
2251:                case REGULAR_FILE_IS_DIRECTORY_ACTION:
2252:                    // SECURITY PERMISSION - MP1
2253:                    return ReuseFactory.getBoolean(actionRegularFile
2254:                            .isDirectory());
2255:
2256:                case REGULAR_FILE_REMOVE_DIRECTORY_ACTION:
2257:                    // SECURITY PERMISSION - MP1, OP5
2258:                    return ReuseFactory.getBoolean(FileUtil
2259:                            .removeDirectory(actionRegularFile));
2260:
2261:                case REGULAR_FILE_RENAME_TO_ACTION:
2262:                    // SECURITY PERMISSION - OP4
2263:                    return ReuseFactory.getBoolean(actionRegularFile
2264:                            .renameTo(actionRegularFile2));
2265:
2266:                case COPY_STORAGE_DIRECTORY_TO_REGULAR_ACTION:
2267:                    // SECURITY PERMISSION - MP1, OP4
2268:                    return ReuseFactory.getBoolean(FileUtil.copyDirectory(
2269:                            storageFactory, actionStorageFile,
2270:                            actionRegularFile, actionBuffer, actionFilter,
2271:                            actionCopySubDirs));
2272:
2273:                case COPY_REGULAR_DIRECTORY_TO_STORAGE_ACTION:
2274:                    // SECURITY PERMISSION - MP1, OP4
2275:                    return ReuseFactory.getBoolean(FileUtil.copyDirectory(
2276:                            (WritableStorageFactory) storageFactory,
2277:                            actionRegularFile, actionStorageFile, actionBuffer,
2278:                            actionFilter));
2279:
2280:                case COPY_REGULAR_FILE_TO_STORAGE_ACTION:
2281:                    // SECURITY PERMISSION - MP1, OP4
2282:                    return ReuseFactory.getBoolean(FileUtil.copyFile(
2283:                            (WritableStorageFactory) storageFactory,
2284:                            actionRegularFile, actionStorageFile));
2285:
2286:                case REGULAR_FILE_LIST_DIRECTORY_ACTION:
2287:                    // SECURITY PERMISSION - MP1
2288:                    return (String[]) (actionRegularFile.list());
2289:
2290:                case STORAGE_FILE_LIST_DIRECTORY_ACTION:
2291:                    // SECURITY PERMISSION - MP1
2292:                    return (String[]) (actionStorageFile.list());
2293:
2294:                case COPY_STORAGE_FILE_TO_REGULAR_ACTION:
2295:                    // SECURITY PERMISSION - MP1, OP4
2296:                    return ReuseFactory.getBoolean(FileUtil.copyFile(
2297:                            (WritableStorageFactory) storageFactory,
2298:                            actionStorageFile, actionRegularFile));
2299:
2300:                case COPY_STORAGE_FILE_TO_STORAGE_ACTION:
2301:                    // SECURITY PERMISSION - MP1, OP4
2302:                    return ReuseFactory.getBoolean(FileUtil.copyFile(
2303:                            (WritableStorageFactory) storageFactory,
2304:                            actionStorageFile, actionToStorageFile));
2305:
2306:                case REGULAR_FILE_GET_CANONICALPATH_ACTION:
2307:                    // SECURITY PERMISSION - MP1
2308:                    return (String) (actionRegularFile.getCanonicalPath());
2309:
2310:                case STORAGE_FILE_GET_CANONICALPATH_ACTION:
2311:                    // SECURITY PERMISSION - MP1
2312:                    return (String) (actionStorageFile.getCanonicalPath());
2313:                }
2314:                return null;
2315:            } // end of run
2316:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.