/* Copyright 2004-2014 Jim Voris
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.qumasoft.server;
import com.qumasoft.qvcslib.QVCSException;
import com.qumasoft.qvcslib.Utility;
import com.qumasoft.qvcslib.commandargs.CheckOutCommandArgs;
import com.qumasoft.qvcslib.commandargs.GetRevisionCommandArgs;
import com.qumasoft.qvcslib.commandargs.LockRevisionCommandArgs;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Operation to check out a revision.
*
* @author Jim Voris
*/
class LogFileOperationCheckOut extends AbstractLogFileOperation {
// Create our logger object
private static final Logger LOGGER = Logger.getLogger("com.qumasoft.server");
private final CheckOutCommandArgs commandLineArgs;
private final String userName;
private String revisionString;
private final String labelString;
private final String fetchToFilename;
private final String fullWorkfileName;
private final String shortWorkfileName;
private final String outputFileName;
private final String checkOutComment;
private final AtomicReference<String> mutableRevisionString;
/**
* Creates a new instance of LogFileOperationCheckOut.
* @param a arguments for the operation. a[0] is the logfileImpl; a[1] is the fetch-to filename; a[2] is the command arguments object.
*/
public LogFileOperationCheckOut(Object[] args) {
super(args, (LogFileImpl) args[0]);
fetchToFilename = (String) args[1];
commandLineArgs = (CheckOutCommandArgs) args[2];
userName = commandLineArgs.getUserName();
revisionString = commandLineArgs.getRevisionString();
labelString = commandLineArgs.getLabel();
checkOutComment = commandLineArgs.getCheckOutComment();
fullWorkfileName = commandLineArgs.getFullWorkfileName();
shortWorkfileName = commandLineArgs.getShortWorkfileName();
outputFileName = commandLineArgs.getOutputFileName();
mutableRevisionString = new AtomicReference<>(revisionString);
}
@Override
public boolean execute() throws QVCSException {
boolean retVal = true;
// Make sure user is on the access list.
getLogFileImpl().makeSureIsOnAccessList(userName);
// If we check locks, then check that no one has locked this revision...
if (getLogFileImpl().getLogFileHeaderInfo().getLogFileHeader().attributes().getIsCheckLock()) {
AtomicInteger revisionIndex = new AtomicInteger();
// If we are doing a checkout by label, make sure the label exists...
if (labelString != null) {
String revisionStringFromLabel = getRevisionStringFromLabel(labelString);
if (revisionStringFromLabel != null) {
mutableRevisionString.set(revisionStringFromLabel);
} else {
retVal = false;
LOGGER.log(Level.INFO, "Label: '" + labelString + "' does not exist for file: " + fullWorkfileName);
}
}
if (retVal) {
// Make sure the revision is not already locked by anyone.
if (getLogFileImpl().isRevisionLocked(mutableRevisionString, revisionIndex)) {
throw new QVCSException("Revision " + mutableRevisionString.get() + " of '" + fullWorkfileName + "' is already locked by "
+ getLogFileImpl().indexToUsername(getLogFileImpl().getRevisionInformation().getRevisionHeader(revisionIndex.get()).getLockerIndex()));
}
// If working on the default revision, this gets filled in for us.
revisionString = mutableRevisionString.get();
}
} else {
// Do not allow a check-out operation on a file that
// does not support locking.
throw new QVCSException(getLogFileImpl().getShortWorkfileName() + " does not support lock checking. Try doing a 'get' instead.");
}
// Do the real work here.
try {
if (retVal) {
// 1. Lock the requested revision
retVal = lockRevision();
// 2. Retrieve the revision into the requested file
if (retVal) {
retVal = getRevision();
commandLineArgs.setRevisionString(mutableRevisionString.get());
}
}
} catch (QVCSException e) {
LOGGER.log(Level.WARNING, "LogFileOperationCheckOut exception: " + e.toString() + ": " + e.getMessage());
LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e));
retVal = false;
} finally {
// Remove any old archives.
getLogFileImpl().getTempFile().delete();
getLogFileImpl().getOldFile().delete();
}
return retVal;
}
private boolean lockRevision() throws QVCSException {
LockRevisionCommandArgs lockCommandLineArgs = new LockRevisionCommandArgs();
lockCommandLineArgs.setUserName(userName);
lockCommandLineArgs.setRevisionString(mutableRevisionString.get());
lockCommandLineArgs.setFullWorkfileName(fullWorkfileName);
lockCommandLineArgs.setShortWorkfileName(shortWorkfileName);
lockCommandLineArgs.setOutputFileName(outputFileName);
lockCommandLineArgs.setCheckOutComment(checkOutComment);
Object[] localArgs = new Object[2];
localArgs[0] = getLogFileImpl();
localArgs[1] = lockCommandLineArgs;
LogFileOperationLockRevision command = new LogFileOperationLockRevision(localArgs);
return command.execute();
}
private boolean getRevision() throws QVCSException {
GetRevisionCommandArgs commandArgs = new GetRevisionCommandArgs();
commandArgs.setUserName(userName);
commandArgs.setRevisionString(mutableRevisionString.get());
commandArgs.setLabel(labelString);
commandArgs.setFullWorkfileName(fullWorkfileName);
commandArgs.setShortWorkfileName(shortWorkfileName);
commandArgs.setOutputFileName(fetchToFilename);
// <editor-fold>
Object[] localArgs = new Object[3];
localArgs[0] = getLogFileImpl();
localArgs[1] = fetchToFilename;
// </editor-fold>
localArgs[2] = commandArgs;
LogFileOperationGetRevision command = new LogFileOperationGetRevision(localArgs);
return command.execute();
}
}