/* 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.clientrequest;
import com.qumasoft.qvcslib.ArchiveDirManagerInterface;
import com.qumasoft.qvcslib.ArchiveInfoInterface;
import com.qumasoft.qvcslib.DirectoryCoordinate;
import com.qumasoft.qvcslib.LogFileInterface;
import com.qumasoft.qvcslib.MutableByteArray;
import com.qumasoft.qvcslib.QVCSConstants;
import com.qumasoft.qvcslib.QVCSException;
import com.qumasoft.qvcslib.ServerResponseFactoryInterface;
import com.qumasoft.qvcslib.SkinnyLogfileInfo;
import com.qumasoft.qvcslib.Utility;
import com.qumasoft.qvcslib.requestdata.ClientRequestResolveConflictFromParentBranchData;
import com.qumasoft.qvcslib.response.ServerResponseInterface;
import com.qumasoft.qvcslib.response.ServerResponseMessage;
import com.qumasoft.qvcslib.response.ServerResponseResolveConflictFromParentBranch;
import com.qumasoft.server.ArchiveDirManagerFactoryForServer;
import com.qumasoft.server.ArchiveInfoForTranslucentBranch;
import com.qumasoft.server.FileIDDictionary;
import com.qumasoft.server.FileIDInfo;
import com.qumasoft.server.ServerTransactionManager;
import com.qumasoft.server.ServerUtility;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* <p>Client request resolve conflict from parent branch.</p> <p>Do the work to remove a conflict with the parent branch. Basically,
* all we need to do is remove the branch label from the archive file... but there is also data that the client will need in order
* to complete the work, and we gather that additional data here, as well as remove the branch label from the archive file.</p>
*
* @author Jim Voris
*/
class ClientRequestResolveConflictFromParentBranch implements ClientRequestInterface {
// Create our logger object
private static final Logger LOGGER = Logger.getLogger("com.qumasoft.server");
private final ClientRequestResolveConflictFromParentBranchData request;
private final MutableByteArray commonAncestorBuffer = new MutableByteArray();
private final MutableByteArray branchParentTipRevisionBuffer = new MutableByteArray();
private final MutableByteArray branchTipRevisionBuffer = new MutableByteArray();
public ClientRequestResolveConflictFromParentBranch(ClientRequestResolveConflictFromParentBranchData data) {
request = data;
}
@Override
public ServerResponseInterface execute(String userName, ServerResponseFactoryInterface response) {
ServerResponseInterface returnObject;
String projectName = request.getProjectName();
String viewName = request.getViewName();
int fileId = request.getFileID();
// Lookup the file.
FileIDInfo fileIDInfo = FileIDDictionary.getInstance().lookupFileIDInfo(projectName, viewName, fileId);
if (fileIDInfo != null) {
try {
DirectoryCoordinate directoryCoordinate = new DirectoryCoordinate(projectName, viewName, fileIDInfo.getAppendedPath());
ArchiveDirManagerInterface directoryManager = ArchiveDirManagerFactoryForServer.getInstance().getDirectoryManager(QVCSConstants.QVCS_SERVER_SERVER_NAME,
directoryCoordinate, QVCSConstants.QVCS_SERVED_PROJECT_TYPE, QVCSConstants.QVCS_SERVER_USER, response, true);
LOGGER.log(Level.INFO, "Resolve conflict from parent branch -- project name: [" + projectName + "] branch name: [" + viewName + "] appended path: ["
+ fileIDInfo.getAppendedPath() + "] short workfile name: [" + fileIDInfo.getShortFilename() + "]");
ArchiveInfoInterface archiveInfo = directoryManager.getArchiveInfo(fileIDInfo.getShortFilename());
if (archiveInfo != null) {
if (archiveInfo instanceof ArchiveInfoForTranslucentBranch) {
ArchiveInfoForTranslucentBranch archiveInfoForTranslucentBranch = (ArchiveInfoForTranslucentBranch) archiveInfo;
Date date = ServerTransactionManager.getInstance().getTransactionTimeStamp(response);
ServerResponseResolveConflictFromParentBranch serverResponseResolveConflictFromParentBranch = buildResponseData(fileIDInfo,
archiveInfoForTranslucentBranch);
if (archiveInfoForTranslucentBranch.resolveConflictFromParentBranch(userName, date)) {
// Send back the logfile info if it's needed for keyword expansion.
if (archiveInfoForTranslucentBranch.getAttributes().getIsExpandKeywords()) {
serverResponseResolveConflictFromParentBranch.setLogfileInfo(archiveInfoForTranslucentBranch.getLogfileInfo());
}
LogFileInterface logFileInterface = (LogFileInterface) archiveInfoForTranslucentBranch;
serverResponseResolveConflictFromParentBranch.setSkinnyLogfileInfo(new SkinnyLogfileInfo(logFileInterface.getLogfileInfo(), File.separator,
logFileInterface.getIsObsolete(), logFileInterface.getDefaultRevisionDigest(), archiveInfoForTranslucentBranch.getShortWorkfileName(),
archiveInfoForTranslucentBranch.getIsOverlap()));
returnObject = serverResponseResolveConflictFromParentBranch;
} else {
// Return an error message.
ServerResponseMessage message = new ServerResponseMessage("Did not succeed in removing branch label for some reason. "
+ "Check the Trunk; maybe is was already removed?.",
projectName, viewName, fileIDInfo.getAppendedPath(), ServerResponseMessage.HIGH_PRIORITY);
message.setShortWorkfileName(fileIDInfo.getShortFilename());
LOGGER.log(Level.WARNING, message.getMessage());
returnObject = message;
}
} else {
// Return an error message.
ServerResponseMessage message = new ServerResponseMessage("Resolve conflict from parent branch is only supported for translucent branches.",
projectName, viewName, fileIDInfo.getAppendedPath(), ServerResponseMessage.HIGH_PRIORITY);
message.setShortWorkfileName(fileIDInfo.getShortFilename());
LOGGER.log(Level.WARNING, message.getMessage());
returnObject = message;
}
} else {
// Return an error message.
ServerResponseMessage message = new ServerResponseMessage("Archive not found for [" + fileIDInfo.getShortFilename() + "]",
projectName, viewName, fileIDInfo.getAppendedPath(), ServerResponseMessage.HIGH_PRIORITY);
message.setShortWorkfileName(fileIDInfo.getShortFilename());
LOGGER.log(Level.WARNING, message.getMessage());
returnObject = message;
}
} catch (QVCSException | IOException e) {
LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e));
// Return an error message.
ServerResponseMessage message = new ServerResponseMessage("Caught exception trying to resolve conflict from parent branch for file: ["
+ fileIDInfo.getShortFilename()
+ "]. Exception string: " + e.getMessage(),
projectName, viewName, fileIDInfo.getAppendedPath(), ServerResponseMessage.HIGH_PRIORITY);
message.setShortWorkfileName(fileIDInfo.getShortFilename());
returnObject = message;
}
} else {
// Return an error message.
ServerResponseMessage message = new ServerResponseMessage("Did not find file information for file id: [" + fileId + "]",
projectName, viewName, "", ServerResponseMessage.HIGH_PRIORITY);
message.setShortWorkfileName("UNKNOWN");
LOGGER.log(Level.WARNING, message.getMessage());
returnObject = message;
}
return returnObject;
}
/**
* Build the data that goes into the response message. This is where we perform the merge to a temp file and discover it that
* merge is successful, etc.
*
* @param archiveInfoForTranslucentBranch the archive info for the translucent branch.
*
* @return a populated response filled in with those 'files' that the client will need to complete the merge.
*/
private ServerResponseResolveConflictFromParentBranch buildResponseData(FileIDInfo fileIDInfo, ArchiveInfoForTranslucentBranch archiveInfoForTranslucentBranch)
throws QVCSException, IOException {
ServerResponseResolveConflictFromParentBranch serverResponseResolveConflictFromParentBranch = new ServerResponseResolveConflictFromParentBranch();
serverResponseResolveConflictFromParentBranch.setAppendedPath(fileIDInfo.getAppendedPath());
serverResponseResolveConflictFromParentBranch.setBranchName(request.getViewName());
serverResponseResolveConflictFromParentBranch.setProjectName(request.getProjectName());
serverResponseResolveConflictFromParentBranch.setShortWorkfileName(fileIDInfo.getShortFilename());
byte[] mergedResultBuffer = ServerUtility.createMergedResultBuffer(archiveInfoForTranslucentBranch, commonAncestorBuffer, branchTipRevisionBuffer,
branchParentTipRevisionBuffer);
if (mergedResultBuffer != null) {
serverResponseResolveConflictFromParentBranch.setMergedResultBuffer(mergedResultBuffer);
serverResponseResolveConflictFromParentBranch.setBranchParentTipRevisionBuffer(branchParentTipRevisionBuffer.getValue());
} else {
serverResponseResolveConflictFromParentBranch.setBranchParentTipRevisionBuffer(branchParentTipRevisionBuffer.getValue());
serverResponseResolveConflictFromParentBranch.setBranchTipRevisionBuffer(branchTipRevisionBuffer.getValue());
serverResponseResolveConflictFromParentBranch.setCommonAncestorBuffer(commonAncestorBuffer.getValue());
}
return serverResponseResolveConflictFromParentBranch;
}
}