com.sun.jts.CosTransactions.LogControl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-embedded-web Show documentation
Show all versions of payara-embedded-web Show documentation
Embedded-Web Distribution of the Payara Project for IBM JDK
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
//----------------------------------------------------------------------------
//
// Module: LogControl.java
//
// Description: Log control file interface.
//
// Product: com.sun.jts.CosTransactions
//
// Author: Simon Holdsworth
//
// Date: March, 1997
//
// Copyright (c): 1995-1997 IBM Corp.
//
// The source code for this program is not published or otherwise divested
// of its trade secrets, irrespective of what has been deposited with the
// U.S. Copyright Office.
//
// This software contains confidential and proprietary information of
// IBM Corp.
//----------------------------------------------------------------------------
package com.sun.jts.CosTransactions;
// Import required classes.
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.logging.LogDomains;
/**This class holds the top level information for an instance of the log,
*
* @version 0.01
*
* @author Simon Holdsworth, IBM Corporation
*
* @see
*/
//----------------------------------------------------------------------------
// CHANGE HISTORY
//
// Version By Change Description
// 0.01 SAJH Initial implementation.
//------------------------------------------------------------------------------
public class LogControl {
private static final StringManager sm = StringManager.getManager(LogControl.class);
private static Logger _logger = LogDomains.getLogger(LogControl.class, LogDomains.TRANSACTION_LOGGER);
/**Constants for file name extensions.
*/
private final static String CUSHION_NAME = "cushion"/*#Frozen*/;
private final static String EXTENT_NAME = "extent."/*#Frozen*/;
private final static String CONTROL_NAME = "control"/*#Frozen*/;
public final static String RECOVERY_STRING_FILE_NAME = "recoveryfile"/*#Frozen*/;
public final static String RECOVERY_LOCK_FILE_NAME = "recoverylockfile"/*#Frozen*/;
//START IASRI 4721336
//private final static String LOG_EXTENSION = ".ld"/*#Frozen*/;
private final static String LOG_EXTENSION = ""/*#Frozen*/;
//END IASRI 4721336
private final static char[] EXTENT_CHARS = { 'e','x','t','e','n','t','.','0','0','0' };
/**Internal instance members
*/
boolean logInitialised = false;
boolean logReadOnly = false;
Vector logHandles = null;
String directoryPath = null;
File controlFile = null;
File cushionFile = null;
//static processSharedLog = GlobLock();
/**Initialises the log in the given directory.
*
* @param coldStart Cold start indicator.
* @param readOnly Read only log indicator.
* @param logDirectory Directory for log files.
*
* @return
*
* @see
*/
synchronized void initLog( boolean coldStart,
boolean readOnly,
String logDirectory ) {
// Trace the global state of the log.
// IF logInitialised
// Unlock the LogGlobalMutex
// Return LOG_SUCCESS
if( logInitialised ) {
return;
}
logReadOnly = readOnly;
// Store the log directory name for use by subsequent log functions.
directoryPath = logDirectory;
// If this is a cold start, then remove all files in the log directory
if( coldStart && !readOnly )
clearDirectory(logDirectory);
// Create the Vector which will hold the LogHandles.
logHandles = new Vector();
// Set the logInitialised flag to TRUE
// Unlock the logGlobalMutex
// Return LOG_SUCCESS
logInitialised = true;
}
/**Opens a log file with the given name and upcall.
*
* @param logName Name of log.
* @param upcallTarget Upcall for log file.
* @param baseNewName Base of new name for log file.
* @param newlyCreated A one-element array to hold the newly created indicator.
*
* @return Handle for the log file.
*
* @exception LogException The open failed.
*
* @see
*/
synchronized LogHandle openFile( String logFileName,
LogUpcallTarget upcallTarget,
String baseNewName,
boolean[] newlyCreated )
throws LogException {
// IF not LogInitialised
// Return LOG_NOT_INITIALISED
if( !logInitialised )
throw new LogException(null,LogException.LOG_NOT_INITIALISED,1);
// If the logid provided is an Alias name, it could be more than 8
// characters. If so, to support the FAT file system, a unique
// 8 character must be generated
// If the name is an Alias name, then the base new name to use will have
// been passed in as a parameter.
String logName = null;
/* if( baseNewName != null )
{
int i = 0;
// Determine the index to start allocating from based on the base
if( baseNewName.length() != 0 )
{
try
{ i = Integer.parseInt(baseNewName.substring(LogHandle.FILENAME_PREFIX_LEN+1,LogHandle.FILENAME_PREFIX_LEN+3),16); }
catch( Throwable e ) {}
i++;
}
// Generate a new name from the base.
boolean logExists;
for( logExists = true;
i <= LogHandle.MAX_NAMES && logExists;
i++)
{
logName = new String(FILENAME_PREFIX);
if( i < 100 ) logName += "0";
if( i < 10 ) logName += "0";
logName += Integer.toString(i);
logExists = checkFileExists(logName,directoryPath);
}
}
else
*/ {
// If the log Id is provided is not an Alias make make sure it
// meets the FAT file system requirements
/* if( logFileName.length() != LogHandle.NAME_LENGTH )
throw new LogException(null,LogException.LOG_INVALID_FILE_DESCRIPTOR,19);
*/
logName = logFileName;
File logDir = directory(logName,directoryPath);
if( !logDir.exists() ) {
boolean created = logDir.mkdirs();
if (!created)
_logger.log(Level.WARNING,"jts.exception_creating_log_directory",logDir);
}
}
// Build name of log's control file, e.g. (.control)
// Issue OPEN request for control file, specifying Read/Write, Create,
// No-share and 'guaranteed write to disk' options
// IF OPEN is not successful
// Return LOG_OPEN_FAILURE
controlFile = controlFile(logName,directoryPath);
cushionFile = cushionFile(logName);
int openOptions = LogFileHandle.OPEN_RDWR |
LogFileHandle.OPEN_CREAT |
LogFileHandle.OPEN_SYNC; // Default open options
if( logReadOnly )
openOptions = LogFileHandle.OPEN_RDONLY;
LogFileHandle controlFH;
try {
controlFH = new LogFileHandle(controlFile,openOptions);
} catch( LogException le ) {
throw new LogException(LogException.LOG_OPEN_FAILURE, 3,
sm.getString("jts.log_create_LogFileHandle_failed", controlFile), le);
}
// Allocate a Log_FileDescriptor block and initialise it
// IF allocate fails
// Close the control file
// Return LOG_INSUFFICIENT_MEMORY
LogHandle logHandle = null;
try {
logHandle = new LogHandle(this,logName,controlFH,upcallTarget); }
catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_INSUFFICIENT_MEMORY,4,
sm.getString("jts.log_create_LogHandle_failed", logName), le);
}
// Call Log_RestoreCushion to create/check the cushion file exists
// for this logfile. If this fails the log cannot be opened.
try {
logHandle.restoreCushion(false);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_INSUFFICIENT_MEMORY,9,
sm.getString("jts.log_cushion_file_failed"), le);
}
// Issue a READ request for the control file, specifying the
// Log_ControlDescriptor structure within the Log_FileDescriptor
// block as the input buffer
// IF not successful (rc == -1)
// Close the control file
// Deallocate the Log_FileDescriptor block
// Return LOG_READ_FAILURE
byte[] controlBytes = new byte[LogControlDescriptor.SIZEOF];
int bytesRead = 0;
try {
bytesRead = controlFH.fileRead(controlBytes);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_READ_FAILURE,5,
sm.getString("jts.log_control_file_read_failed"), le);
}
if( bytesRead == 0 ) {
// IF the READ returned EOF (rc == 0), continue with initialisation of
// the Log_ControlDescriptor structure within the
// Log_FileDescriptor block
// - Initialise the log head LSN to LOG_NULL_LSN
// - Initialise the log tail LSN to LOG_FIRST_LSN
// - Initialise the next free LSN to LOG_FIRST_LSN
// - Initialise the RestartDataLength in the Log_FileDescriptor
// block to 0
//
// Set NewlyCreated parameter to TRUE
//
// Pre-allocate all the file storage for the control file
//
// Set RecordsWritten to LOG_CONTROL_FORCE_INTERVAL so on
// the first write to the log the newly created control data
// is written to disk. If this is not done then data could be lost.
//
// Write the control data to file
//
// Open the first extent file and allocate the storage it requires.
// If either step fails close and erase the control file and
// return LOG_INSUFFICIENT_STORAGE.
logHandle.logControlDescriptor.headLSN.copy(LogLSN.NULL_LSN);
logHandle.logControlDescriptor.tailLSN.copy(LogLSN.FIRST_LSN);
logHandle.logControlDescriptor.nextLSN.copy(LogLSN.FIRST_LSN);
logHandle.restartDataLength = 0;
logHandle.recordsWritten = LogHandle.CONTROL_FORCE_INTERVAL;
newlyCreated[0] = true;
if( !logReadOnly ) {
int bytesWritten;
try {
controlFH.allocFileStorage(LogHandle.CONTROL_FILE_SIZE);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_WRITE_FAILURE,6,
sm.getString("jts.log_allocate_failed"), le);
}
logHandle.logControlDescriptor.toBytes(controlBytes,0);
try {
bytesWritten = controlFH.fileWrite(controlBytes);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_WRITE_FAILURE,7,
sm.getString("jts.log_control_file_write_failed"), le);
}
LogExtent logEDP = null;
try {
logEDP = logHandle.openExtent(logHandle.logControlDescriptor.nextLSN.extent);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_NO_SPACE,10,
sm.getString("jts.log_open_extend_failed"), le);
}
try {
logEDP.fileHandle.allocFileStorage(LogHandle.ALLOCATE_SIZE);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_NO_SPACE,11,
sm.getString("jts.log_allocate_failed"), le);
}
logHandle.chunkRemaining = LogHandle.ALLOCATE_SIZE;
}
}
// Otherwise the log already exists.
else {
int timeStampRec1; // The time stamp in restart rec 1
int timeStampRec2; // The time stamp in restart rec 2
int lengthRec1; // The length of restart record 1
int lengthRec2; // The length of restart record 1
// Set NewlyCreated parameter to FALSE
newlyCreated[0] = false;
// Open all of the active extents and
// rebuild the extent table, starting form the extent
// containing the Tail LSN and finishing with the extent
// containing the Head LSN
logHandle.logControlDescriptor = new LogControlDescriptor(controlBytes,0);
LogExtent logEDP = null;
for( int currentExtent = logHandle.logControlDescriptor.tailLSN.extent;
currentExtent <= logHandle.logControlDescriptor.headLSN.extent ||
currentExtent <= logHandle.logControlDescriptor.nextLSN.extent;
currentExtent++)
try {
logEDP = logHandle.openExtent(currentExtent);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_OPEN_EXTENT_FAILURE,19,
sm.getString("jts.log_open_extend_failed"), le);
}
// Read the restart data for restart record one
// If the read failed then
// Close the control file
// Deallocate the Log_FileDescriptor block
// Return LOG_READ_FAILURE
int[] restartValues1 = new int[2];
int[] restartValues2 = new int[2];
try {
logHandle.checkRestart(controlFH,1,restartValues1);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_READ_FAILURE,8,
sm.getString("jts.log_read_restart_data_failed"), le);
}
// Check that the record length was not equal to zero
// IF the record length was not equal to zero
// READ the next restart record
// IF ( (Length2 !=0) && (Time2 > Time1)
// THEN CurrentValid is 2
// ELSE CurrentValid is 1
// BUGFIX(Ram Jeyaraman) Always check both the restart records,
// even though the first record might have zero data length.
// It is possible, that the second record might
// have non-zero data length with a later
// timestamp, even though the first record has zero data length.
// Fix is to comment out the check below.
//if (restartValues1[0] != 0)
{
// If the read failed then
// Close the control file
// Deallocate the Log_FileDescriptor block
// Return LOG_READ_FAILURE
try {
logHandle.checkRestart(controlFH,2,restartValues2);
} catch( LogException le ) {
controlFH.destroy();
throw new LogException(LogException.LOG_READ_FAILURE,9,
sm.getString("jts.log_check_restart_failed"), le);
}
if( restartValues2[0] != 0 &&
restartValues2[1] > restartValues1[1] ) {
logHandle.activeRestartVersion = 2;
logHandle.restartDataLength = restartValues2[0];
} else {
logHandle.activeRestartVersion = 1;
logHandle.restartDataLength = restartValues1[0];
}
}
if( logHandle.logControlDescriptor.headLSN.isNULL() )
logHandle.recordsWritten = LogHandle.CONTROL_FORCE_INTERVAL;
}
// Add the Log_FileDescriptor block to the head of the
// (LogFileDescriptorHead) chain hung off the RCA and update the backward
// chain pointer of the block which was previously at the head of the chain.
logHandles.addElement(logHandle);
// IF the head LSN in Log_ControlDescriptor != LOG_NULL_LSN
// Build the extent file name from the head LSN
// Issue an OPEN request for the file
if( !logHandle.logControlDescriptor.headLSN.isNULL() ) {
int offset; // Present offset in the open extent
LogRecordHeader extentRec, // An extent record header
headRec, // An extent record header
linkRec; // An extent record header
boolean lastValidRead = false; // Has the last valid record be read
LogExtent logEDP = null;
// IF not successful (rc == -1)
// Close the control file
// Unchain the LogFDP and free up the storage
// Return LOG_OPEN_FAILURE
// Allocate a Log_ExtentDescriptor block and initialise it
// Hash the extent number to find the anchor for this extent in the
// hash table and add it to the head of the chain
// Move the file pointer to the head LSN record (using LSEEK)
try {
logEDP = logHandle.positionFilePointer(logHandle.logControlDescriptor.headLSN,
0,LogExtent.ACCESSTYPE_READ); }
catch( LogException le ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(LogException.LOG_OPEN_FAILURE,10,
sm.getString("jts.log_position_file_pointer_failed"), le);
}
// Issue a READ for the record header
// IF the read is not successful (rc <= 0)
// Close the control file
// Deallocate newly acquired control blocks
// Return LOG_READ_FAILURE
//
// Check that the LSN in the record header matches the head LSN
// IF there is a mismatch
// Deallocate newly acquired control blocks
// Return LOG_CORRUPTED
byte[] headerBytes = new byte[LogRecordHeader.SIZEOF];
try {
bytesRead = logEDP.fileHandle.fileRead(headerBytes);
} catch( LogException le ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(le.errorCode,11,
sm.getString("jts.log_read_header_failed"), le);
}
extentRec = new LogRecordHeader(headerBytes,0);
if( !extentRec.currentLSN.equals(logHandle.logControlDescriptor.headLSN) ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(null,LogException.LOG_CORRUPTED,12);
}
// Copy the record header to HEADERCOPY
// Move the file pointer to the 'next LSN' in record header
logEDP.cursorPosition += bytesRead;
headRec = new LogRecordHeader();
headRec.copy(extentRec);
offset = headRec.nextLSN.offset;
try {
logEDP = logHandle.positionFilePointer(extentRec.nextLSN,0,LogExtent.ACCESSTYPE_READ);
} catch( LogException le ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(LogException.LOG_OPEN_FAILURE,13,
sm.getString("jts.log_position_file_pointer_failed"), le);
}
linkRec = new LogRecordHeader();
// LOOP until last valid log record has been read
lastValidRead = false;
do {
// Issue a read for the record header
offset = extentRec.nextLSN.offset;
try {
bytesRead = logEDP.fileHandle.fileRead(headerBytes);
} catch( LogException le ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(LogException.LOG_READ_FAILURE,14,
sm.getString("jts.log_read_header_failed"), le);
}
if( bytesRead == -1 ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(null,LogException.LOG_READ_FAILURE,14);
}
extentRec = new LogRecordHeader(headerBytes,0);
logEDP.cursorPosition += bytesRead;
// IF the LSN in the record header matches the LSN of the
// current position in the extent file
if( extentRec.currentLSN.offset == offset ) {
// IF its a link record
if( extentRec.recordType == LogHandle.LINK ) {
// Copy it to LINKCOPY
// 'Move' the file pointer to the NextRecord value (in the next extent file)
// Iterate.
linkRec.copy(extentRec);
try {
logEDP = logHandle.positionFilePointer(extentRec.nextLSN,0,LogExtent.ACCESSTYPE_READ);
} catch( LogException le ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(le.errorCode,15,
sm.getString("jts.log_position_file_pointer_failed"), le);
}
continue;
} else
// IF LINKCOPY is not null AND LINKCOPY.NextRecord LSN &lnot.= ThisRecord LSN
// Set LINKCOPY to null
if( !linkRec.currentLSN.isNULL() &&
!linkRec.nextLSN.equals(extentRec.currentLSN) )
linkRec = new LogRecordHeader();
// Copy the record header to HEADERCOPY
// Use the NextRecord value to move the file pointer to the next record header
headRec.copy(extentRec);
try {
logEDP = logHandle.positionFilePointer(extentRec.nextLSN,0,LogExtent.ACCESSTYPE_READ);
} catch( Throwable e ) {}
} else {
LogRecordEnding endRec; // An ending record type
lastValidRead = true;
// Use the ThisRecord value from HEADERCOPY together with the
// RecordLength value to calculate the position of the previous
// Log_RecordEnding structure
//
// LSEEK to this position and read it
try {
logEDP = logHandle.positionFilePointer(headRec.currentLSN,
LogRecordHeader.SIZEOF+headRec.recordLength,
LogExtent.ACCESSTYPE_READ);
} catch( LogException le ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(le.errorCode,16,
sm.getString("jts.log_position_file_pointer_failed"), le);
}
byte[] endingBytes = new byte[LogRecordEnding.SIZEOF];
try {
bytesRead = logEDP.fileHandle.fileRead(endingBytes);
} catch( LogException le ) {
controlFH.destroy();
removeFile(logHandle);
throw new LogException(le.errorCode,17, null, le);
}
endRec = new LogRecordEnding(endingBytes,0);
logEDP.cursorPosition += bytesRead;
// IF its value is the same as ThisRecord LSN This is the last valid record
// Update head LSN in control data with ThisRecord LSN
// Update next LSN in control data with the NextRecord LSN
if( endRec.currentLSN.equals(headRec.currentLSN) ) {
logHandle.logControlDescriptor.headLSN.copy(headRec.currentLSN);
logHandle.logControlDescriptor.nextLSN.copy(headRec.nextLSN);
}
// This is an invalid record, so record details of previous valid record
// IF LINKCOPY is null
// Update head LSN in control data with the PreviousRecord LSN
// Update next LSN in control data with ThisRecord LSN
else {
if( linkRec.currentLSN.isNULL() ) {
logHandle.logControlDescriptor.headLSN.copy(headRec.previousLSN);
logHandle.logControlDescriptor.nextLSN.copy(headRec.currentLSN);
}
// Otherwise update head LSN in control data with value from LINKCOPY
else {
logHandle.logControlDescriptor.headLSN.copy(linkRec.previousLSN);
logHandle.logControlDescriptor.nextLSN.copy(linkRec.currentLSN);
}
}
}
// Increase the number of records written since the last force
logHandle.recordsWritten++;
}
while( !lastValidRead );
}
// Store the address of the Log_FileDescriptor block into its BlockValid field
logHandle.blockValid = logHandle;
return logHandle;
}
/**Cleans up the given log file.
*
* @param logHandle The log to clean up.
*
* @return
*
* @exception LogException The operation failed.
*
* @see
*/
synchronized void cleanUp( LogHandle logHandle )
throws LogException {
// IF not LogInitialised Return LOG_NOT_INITIALISED
if( !logInitialised )
throw new LogException(null,LogException.LOG_NOT_INITIALISED,1);
// Check BlockValid field in Log_FileDescriptor block and
// ensure it is valid
// IF not valid Log_FileDescriptor
// Return LOG_INVALID_FILE_DESCRIPTOR
if( logHandle == null || logHandle.blockValid != logHandle )
throw new LogException(LogException.LOG_INVALID_FILE_DESCRIPTOR,2,
sm.getString("jts.log_invalid_file_descriptor", logHandle), (Throwable) null);
// Set the block valid to NULL
logHandle.blockValid = null;
// Remove all extent entries from the log file's extent hash table
logHandle.cleanUpExtents();
// Unchain the Log_FileDescriptor block from the RCA chain. The
// mutices contained in the FD latch structure will already have been
// freed up when the AS process which owned them died. We indicate this
// by setting the ProcessOwnsLatch parameter to FALSE.
removeFile(logHandle);
}
/**Determines whether the given named log exists in the given directory.
*
* @param logId The log identifier.
* @param logDirectory The log directory.
*
* @return Indicates whether the file exists.
*
* @see
*/
static boolean checkFileExists( String logId,
String logDirectory ) {
//START IASRI 4730519
if(logDirectory==null)
return false;
//END IASRI 4730519
boolean exists = controlFile(logId,logDirectory).exists();
return exists;
}
/**Removes the log file from the chain.
*
* @param logHandle
*
* @return
*
* @see
*/
synchronized void removeFile( LogHandle logHandle ) {
// Unchain the Log_FileDescriptor block from the RCA chain
logHandles.removeElement(logHandle);
// Clear the BlockValid field in the Log_FileDescriptor block
logHandle.blockValid = null;
}
/**Dumps the state of the object.
*
* @param
*
* @return
*
* @see
*/
//----------------------------------------------------------------------------
void dump() {
// If the log has been initialised the pointer to the global
// data will have been initialised. So, if the pointer to the
// global data is not NULL, dump out the its contents.
}
/**Clears out all log files from the given directory.
*
* @param logDir
*
* @return
*
* @see
*/
static void clearDirectory( String logDir ) {
// Find each control file in turn and then delete all files that
// begin with the same name. This will delete all files associated
// with that log (including the control file so that it is not found
// again next time through the loop)
File directory = new File(logDir);
String[] allFiles = directory.list();
for( int i = 0; i < allFiles.length; i++ ) {
// Determine if the file is actually a log subdirectory. If so, use it's name
// to delete all associated log files.
if( allFiles[i].endsWith(LOG_EXTENSION) ) {
//Start IASRI 4720539
final File logFileDir = new File(directory,allFiles[i]);
if( logFileDir.isDirectory() ) {
final String[] logFiles = logFileDir.list();
/*
for( int j = 0; j < logFiles.length; j++ )
new File(logFileDir,logFiles[j]).delete();
logFileDir.delete();
*/
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run(){
for( int j = 0; j < logFiles.length; j++ ){
new File(logFileDir,logFiles[j]).delete();
}
return null;
}
}
);
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run(){
logFileDir.delete();
return null;
}
}
);
}
//End IASRI 4720539
}
}
}
/**Builds a log extent file.
*
* @param logId Log identifier.
* @param extent Extent number.
*
* @return A File object representing the extent file.
*
* @see
*/
File extentFile( String logId,
int extent ) {
char[] buff = (char[])EXTENT_CHARS.clone();
int tmpExtent = extent / LogExtent.EXTENT_RADIX;
int extentLow = extent % LogExtent.EXTENT_RADIX;
int extentMid = tmpExtent % LogExtent.EXTENT_RADIX;
int extentHigh = tmpExtent / LogExtent.EXTENT_RADIX;
buff[7] = (char)(extentHigh + (extentHigh > 9 ? 'A'-10 : '0'));
buff[8] = (char)(extentMid + (extentMid > 9 ? 'A'-10 : '0'));
buff[9] = (char)(extentLow + (extentLow > 9 ? 'A'-10 : '0'));
String fileName = new String(buff);
File result = new File(directory(logId,directoryPath),fileName);
return result;
}
/**Builds a log control file.
*
* @param logId Log identifier.
* @param logDir Log directory.
*
* @return A File object representing the control file.
*
* @see
*/
final static File controlFile( String logId, String logDir ) {
File result = new File(directory(logId,logDir),CONTROL_NAME);
return result;
}
/**Builds a log cushion file.
*
* @param logId Log identifier.
*
* @return A File object representing the cushion file.
*
* @see
*/
final File cushionFile( String logId ) {
File result = new File(directory(logId,directoryPath),CUSHION_NAME);
return result;
}
/**Builds a log directory file.
*
* @param logId Log identifier.
* @param logDir Base log directory.
*
* @return A File object representing the directory.
*
* @see
*/
final static File directory( String logId, String logDir ) {
//START IASRI 4721336
//START IASRI 4730519
if(logDir==null) //It should not be null
return new File( "." + File.separator + logId + LOG_EXTENSION);
//END IASRI 4730519
return new File(logDir);
//END IASRI 4721336
}
final static File recoveryIdentifierFile(String logId, String logDir) {
File result = new File(directory(logId,logDir),RECOVERY_STRING_FILE_NAME);
return result;
}
public final static File recoveryLockFile(String logId, String logDir) {
File dir = directory(logId,logDir);
if( !dir.exists() ) {
boolean created = dir.mkdirs();
if (!created)
_logger.log(Level.WARNING,"jts.exception_creating_log_directory",dir);
}
File result = new File(dir,RECOVERY_LOCK_FILE_NAME);
return result;
}
/**
* Returns the log directory name
*/
public static String getLogPath() {
String logPath = null;
int[] result = new int[1];
logPath = Configuration.getDirectory(Configuration.LOG_DIRECTORY,
Configuration.JTS_SUBDIRECTORY,
result);
// If a default was used, display a message.
if( result[0] == Configuration.DEFAULT_USED ||
result[0] == Configuration.DEFAULT_INVALID ) {
// In the case where the SOMBASE default is used, only display a message
// if an invalid value was specified in the environment value.
if( logPath.length() > 0 ) {
_logger.log(Level.WARNING,"jts.invalid_log_path",logPath);
}
// In the case where the SOMBASE default is invalid, the value returned is
// the invalid default. We then default to the current directory.
if( result[0] == Configuration.DEFAULT_INVALID ) {
_logger.log(Level.WARNING,"jts.invalid_default_log_path");
logPath = "."/*#Frozen*/;
}
}
return logPath;
}
}