/* 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.guitools.qwin.operation; import com.qumasoft.guitools.qwin.ProjectTreeControl; import com.qumasoft.guitools.qwin.QWinFrame; import com.qumasoft.guitools.qwin.QWinUtility; import com.qumasoft.qvcslib.AbstractProjectProperties; import com.qumasoft.qvcslib.ClientTransactionManager; import com.qumasoft.qvcslib.DirectoryCoordinate; import com.qumasoft.qvcslib.DirectoryManagerFactory; import com.qumasoft.qvcslib.DirectoryManagerInterface; import com.qumasoft.qvcslib.FilePromotionInfo; import com.qumasoft.qvcslib.MergedInfoInterface; import com.qumasoft.qvcslib.PromoteFileResults; import com.qumasoft.qvcslib.QVCSConstants; import com.qumasoft.qvcslib.QVCSException; import com.qumasoft.qvcslib.TransportProxyFactory; import com.qumasoft.qvcslib.TransportProxyInterface; import com.qumasoft.qvcslib.UserLocationProperties; import com.qumasoft.qvcslib.Utility; import java.io.File; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; /** * Promote a file. * * @author Jim Voris */ public class OperationPromoteFile extends OperationBaseClass { // Create our logger object private static final Logger LOGGER = Logger.getLogger("com.qumasoft.guitools.qwin"); private final List<FilePromotionInfo> filePromotionInfoList; private final String parentBranchName; private final String branchToPromoteFrom; /** * Operation promote file constructor. * * @param serverName the server name. * @param projectName the project name. * @param viewName the view name. * @param branchName the name of the branch we are promoting. * @param userLocationProperties the user location properties. * @param filePromotionList the list of files to promote. */ public OperationPromoteFile(String serverName, String projectName, String viewName, String branchName, UserLocationProperties userLocationProperties, List<FilePromotionInfo> filePromotionList) { super(null, serverName, projectName, viewName, userLocationProperties); this.filePromotionInfoList = filePromotionList; this.parentBranchName = viewName; this.branchToPromoteFrom = branchName; } @Override public void executeOperation() { if (filePromotionInfoList != null && filePromotionInfoList.size() > 0) { final List<FilePromotionInfo> finalFilePromotionInfoList = this.filePromotionInfoList; final AbstractProjectProperties projectProperties = ProjectTreeControl.getInstance().getActiveProject(); final TransportProxyInterface fTransportProxy = TransportProxyFactory.getInstance().getTransportProxy(QWinFrame.getQWinFrame().getActiveServerProperties()); if (fTransportProxy != null) { LOGGER.log(Level.INFO, "=========== Transport proxy transport name: [" + fTransportProxy.getTransportName() + "] user name: [" + fTransportProxy.getUsername() + "]"); } else { LOGGER.log(Level.WARNING, "null value for transport proxy!!!"); } Runnable later = new Runnable() { @Override public void run() { int transactionId = ClientTransactionManager.getInstance().sendBeginTransaction(fTransportProxy); try { for (FilePromotionInfo filePromotionInfo : finalFilePromotionInfoList) { try { promoteFile(projectProperties, filePromotionInfo); } catch (QVCSException e) { LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e)); } } } catch (Exception e) { LOGGER.log(Level.WARNING, Utility.expandStackTraceToString(e)); } finally { ClientTransactionManager.getInstance().sendEndTransaction(fTransportProxy, transactionId); } } void promoteFile(AbstractProjectProperties projectProperties, FilePromotionInfo filePromotionInfo) throws QVCSException { final String finalParentBranchName = getParentBranchName(); final String finalBranchToPromoteFrom = getBranchToPromoteFrom(); MergedInfoInterface mergedInfo = deduceMergedInfo(projectProperties, filePromotionInfo); PromoteFileResults promoteFileResults; switch (filePromotionInfo.getTypeOfMerge()) { case SIMPLE_MERGE_TYPE: promoteFileResults = mergedInfo.promoteFile(getProjectName(), finalBranchToPromoteFrom, finalParentBranchName, filePromotionInfo, filePromotionInfo.getFileId()); if (promoteFileResults != null) { boolean overlapDetectedFlag = false; String workfileBase = getUserLocationProperties().getWorkfileLocation(getServerName(), getProjectName(), getViewName()); if (promoteFileResults.getMergedResultBuffer() != null) { // Write this to the workfile location for this file, as it is our best guess at a merged result writeMergedResultToWorkfile(mergedInfo, workfileBase, promoteFileResults.getMergedResultBuffer()); } if (promoteFileResults.getBranchTipRevisionBuffer() != null) { writeConflictFile(mergedInfo, "branchTip", workfileBase, promoteFileResults.getBranchTipRevisionBuffer()); overlapDetectedFlag = true; } if (promoteFileResults.getCommonAncestorBuffer() != null) { writeConflictFile(mergedInfo, "commonAncestor", workfileBase, promoteFileResults.getCommonAncestorBuffer()); overlapDetectedFlag = true; } if (overlapDetectedFlag) { writeConflictFile(mergedInfo, "branchParentTip", workfileBase, promoteFileResults.getBranchParentTipRevisionBuffer()); } QWinFrame.getQWinFrame().refreshCurrentView(); if (overlapDetectedFlag) { // TODO -- Ideally, we should automatically launch the visual merge tool here. StringBuilder stringBuffer = new StringBuilder(); stringBuffer.append("Overlap detected when merging [").append(mergedInfo.getShortWorkfileName()) .append("]. You will need to perform a manual merge."); final String message = stringBuffer.toString(); QWinUtility.logProblem(Level.INFO, message); // Show the message box on the Swing thread. Runnable later = new Runnable() { @Override public void run() { // Let the user know they'll need to perform the merge manually. JOptionPane.showConfirmDialog(QWinFrame.getQWinFrame(), message, "Merge Overlap Detected", JOptionPane.PLAIN_MESSAGE); } }; SwingUtilities.invokeLater(later); } } break; case CHILD_CREATED_MERGE_TYPE: promoteFileResults = mergedInfo.promoteFile(getProjectName(), finalBranchToPromoteFrom, finalParentBranchName, filePromotionInfo, filePromotionInfo.getFileId()); if (promoteFileResults != null) { String workfileBase = getUserLocationProperties().getWorkfileLocation(getServerName(), getProjectName(), getViewName()); if (promoteFileResults.getMergedResultBuffer() != null) { // Write this to the workfile location for this file, as it is our best guess at a merged result writeMergedResultToWorkfile(mergedInfo, workfileBase, promoteFileResults.getMergedResultBuffer()); } } break; default: // Not supported yet. throw new UnsupportedOperationException("Not supported yet."); } } }; // Put all this on a separate worker thread. new Thread(later).start(); } } String getParentBranchName() { return this.parentBranchName; } String getBranchToPromoteFrom() { return this.branchToPromoteFrom; } private MergedInfoInterface deduceMergedInfo(AbstractProjectProperties projectProperties, FilePromotionInfo filePromotionInfo) throws QVCSException { String workfileBase = getUserLocationProperties().getWorkfileLocation(getServerName(), getProjectName(), getViewName()); String appendedPath = filePromotionInfo.getAppendedPath(); String workfileDirectory; if (appendedPath.length() > 0) { workfileDirectory = workfileBase + File.separator + appendedPath; } else { workfileDirectory = workfileBase; } // Need to build the directory manager from scratch, since there is no guarantee that it has been built yet. DirectoryManagerInterface directoryManager; switch (filePromotionInfo.getTypeOfMerge()) { case CHILD_CREATED_MERGE_TYPE: DirectoryCoordinate directoryCoordinate = new DirectoryCoordinate(getProjectName(), branchToPromoteFrom, filePromotionInfo.getAppendedPath()); directoryManager = DirectoryManagerFactory.getInstance().getDirectoryManager(getServerName(), directoryCoordinate, QVCSConstants.QVCS_REMOTE_PROJECT_TYPE, projectProperties, workfileDirectory, null, false); break; default: DirectoryCoordinate defaultDirectoryCoordinate = new DirectoryCoordinate(getProjectName(), getViewName(), filePromotionInfo.getAppendedPath()); directoryManager = DirectoryManagerFactory.getInstance().getDirectoryManager(getServerName(), defaultDirectoryCoordinate, QVCSConstants.QVCS_REMOTE_PROJECT_TYPE, projectProperties, workfileDirectory, null, false); break; } MergedInfoInterface mergedInfo = directoryManager.getMergedInfo(filePromotionInfo.getShortWorkfileName()); return mergedInfo; } }