/* 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.FileTableModel; import com.qumasoft.guitools.qwin.dialog.ParentChildProgressDialog; import com.qumasoft.guitools.qwin.ParentProgressDialogInterface; import com.qumasoft.guitools.qwin.dialog.ProgressDialog; import com.qumasoft.guitools.qwin.ProgressDialogInterface; import com.qumasoft.guitools.qwin.QWinFrame; import com.qumasoft.guitools.qwin.QWinUtility; import com.qumasoft.qvcslib.ArchiveDirManagerProxy; import com.qumasoft.qvcslib.KeywordExpansionContext; import com.qumasoft.qvcslib.KeywordManagerFactory; import com.qumasoft.qvcslib.MergedInfoInterface; import com.qumasoft.qvcslib.QVCSException; import com.qumasoft.qvcslib.UserLocationProperties; import com.qumasoft.qvcslib.Utility; import com.qumasoft.qvcslib.WorkFile; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import javax.swing.JTable; import javax.swing.SwingUtilities; /** * Operation base class. * @author Jim Voris */ public abstract class OperationBaseClass { static final int MINIMUM_TO_SHOW_PROGRESS = 10; private final JTable fileTable; private final String serverName; private final String projectName; private final String viewName; private final UserLocationProperties userLocationProperties; // KLUDGE -- use this to store the progress dialog that we create on the Swing thread. private static ProgressDialog staticProgressDialog; private static ParentChildProgressDialog staticParentChildProgressDialog; /** * Creates a new instance of OperationBaseClass. * * @param ft the file table. * @param server name of the server * @param project name of the project. * @param view name of the view. * @param userLocationProps user location properties. */ public OperationBaseClass(JTable ft, final String server, final String project, final String view, UserLocationProperties userLocationProps) { fileTable = ft; serverName = server; projectName = project; viewName = view; userLocationProperties = userLocationProps; } /** * Perform the operation. */ public abstract void executeOperation(); // Return an ArrayList of MergedInfo objects that are associated with // the selected files. protected List<MergedInfoInterface> getSelectedFiles() { int[] selectedRows = getFileTable().getSelectedRows(); FileTableModel dataModel = (FileTableModel) getFileTable().getModel(); List<MergedInfoInterface> mergedInfoArray = new ArrayList<>(); // Create a list of the selected files. for (int i = 0; i < selectedRows.length; i++) { // Save the names of the archives we'll work on. int selectedRowIndex = selectedRows[i]; MergedInfoInterface mergedInfo = dataModel.getMergedInfo(selectedRowIndex); mergedInfoArray.add(mergedInfo); } return mergedInfoArray; } protected int getSelectedFileCount() { int retVal = 0; if (getFileTable() != null) { retVal = getFileTable().getSelectedRowCount(); } return retVal; } protected MergedInfoInterface getFocusedFile() { MergedInfoInterface mergedInfo = null; if (getSelectedFileCount() > 0) { int focusIndex = QWinFrame.getQWinFrame().getRightFilePane().getFocusIndex(); if (focusIndex >= 0) { FileTableModel dataModel = (FileTableModel) getFileTable().getModel(); mergedInfo = dataModel.getMergedInfo(focusIndex); } } return mergedInfo; } protected JTable getFileTable() { return fileTable; } protected String getServerName() { return serverName; } protected String getProjectName() { return projectName; } protected String getViewName() { return viewName; } protected boolean createWorkfileDirectory(MergedInfoInterface mergedInfo) { boolean retVal = false; String workfileBase = getUserLocationProperties().getWorkfileLocation(getServerName(), getProjectName(), getViewName()); String fullWorkfileDirectory = workfileBase + File.separator + mergedInfo.getArchiveDirManager().getAppendedPath(); File workfileFile = new File(fullWorkfileDirectory); if (!workfileFile.exists()) { if (!workfileFile.mkdirs()) { QWinUtility.logProblem(Level.INFO, "Could not create workfile directory: " + fullWorkfileDirectory); } else { retVal = true; } } else { retVal = true; } return retVal; } protected UserLocationProperties getUserLocationProperties() { return userLocationProperties; } /** * Create a progress dialog. * @param progressAction what we're doing. * @param size the maximum progress value. * @return the created ProgressDialog. */ public static ProgressDialog createProgressDialog(final String progressAction, final int size) { ProgressDialog progressMonitor = null; if (SwingUtilities.isEventDispatchThread()) { // Create a progress dialog. progressMonitor = new ProgressDialog(QWinFrame.getQWinFrame(), true, 0, size); progressMonitor.setAction(progressAction); } else { Runnable create = new Runnable() { @Override public void run() { // Create a progress dialog. staticProgressDialog = new ProgressDialog(QWinFrame.getQWinFrame(), true, 0, size); staticProgressDialog.setAction(progressAction); } }; try { SwingUtilities.invokeAndWait(create); progressMonitor = staticProgressDialog; } catch (InterruptedException | InvocationTargetException e) { QWinUtility.logProblem(Level.WARNING, "Caught exception: " + e.getClass().toString() + " : " + e.getLocalizedMessage()); } } return progressMonitor; } /** * Initialize the given progress dialog. * @param action to say what is going on. * @param min the minimum value for the progress bar. * @param max the maximum value for the progress bar. * @param progressDialog the progress dialog to be initialized. */ public static void initProgressDialog(final String action, final int min, final int max, final ProgressDialogInterface progressDialog) { // Update the progress monitor Runnable later = new Runnable() { @Override public void run() { progressDialog.initProgressBar(min, max); progressDialog.setAction(action); } }; javax.swing.SwingUtilities.invokeLater(later); } /** * Update the given progress dialog. * @param progress how far along we are. * @param activity what we're doing. * @param progressDialog the progress dialog to update. */ public static void updateProgressDialog(final int progress, final String activity, final ProgressDialogInterface progressDialog) { // Update the progress monitor Runnable later = new Runnable() { @Override public void run() { if ((progress > MINIMUM_TO_SHOW_PROGRESS) && !progressDialog.getProgressDialogVisibleFlag()) { progressDialog.setVisible(true); progressDialog.setProgressDialogVisibleFlag(true); } progressDialog.setProgress(progress); progressDialog.setActivity(activity); } }; javax.swing.SwingUtilities.invokeLater(later); } /** * Create a parent-child progress dialog. * @param progressAction the action to show. * @param size the maximum value for the parent's progress bar. * @return a parent-child progress dialog. */ public static ParentChildProgressDialog createParentProgressDialog(final String progressAction, final int size) { ParentChildProgressDialog progressMonitor = null; if (SwingUtilities.isEventDispatchThread()) { // Create a progress dialog. progressMonitor = new ParentChildProgressDialog(QWinFrame.getQWinFrame(), true, 0, size); progressMonitor.setParentAction(progressAction); } else { Runnable create = new Runnable() { @Override public void run() { // Create a progress dialog. staticParentChildProgressDialog = new ParentChildProgressDialog(QWinFrame.getQWinFrame(), true, 0, size); staticParentChildProgressDialog.setParentAction(progressAction); } }; try { SwingUtilities.invokeAndWait(create); progressMonitor = staticParentChildProgressDialog; } catch (InterruptedException | InvocationTargetException e) { QWinUtility.logProblem(Level.WARNING, "Caught exception: " + e.getClass().toString() + " : " + e.getLocalizedMessage()); } } return progressMonitor; } static void initParentChildProgressDialog(final String action, final int min, final int max, final ParentProgressDialogInterface progressDialog) { // Update the progress monitor Runnable later = new Runnable() { @Override public void run() { progressDialog.initParentProgressBar(min, max); progressDialog.setParentAction(action); } }; javax.swing.SwingUtilities.invokeLater(later); } /** * Update a parent-child progress dialog. * @param i the parent progress. * @param activity what is happening. * @param progressDialog the dialog that we are to update. */ public static void updateParentChildProgressDialog(final int i, final String activity, final ParentProgressDialogInterface progressDialog) { // Update the progress monitor Runnable later = new Runnable() { @Override public void run() { progressDialog.setParentProgress(i); progressDialog.setParentActivity(activity); } }; javax.swing.SwingUtilities.invokeLater(later); } protected void writeMergedResultToWorkfile(MergedInfoInterface mergedInfo, String workfileBase, byte[] buffer) { java.io.FileOutputStream outputStream = null; ArchiveDirManagerProxy dirManagerProxy; try { String fullWorkfileName = constructFullWorkfileName(mergedInfo, workfileBase); WorkFile workfile = new WorkFile(fullWorkfileName); if (!mergedInfo.getWorkfileExists()) { createWorkfileDirectory(mergedInfo); } if (workfile.exists()) { workfile.setReadWrite(); } // Figure out our directory manager. dirManagerProxy = (ArchiveDirManagerProxy) mergedInfo.getArchiveDirManager(); // See if we have to worry about keyword expansion... if (mergedInfo.getKeywordExpansionAttribute() && dirManagerProxy != null) { try { outputStream = new java.io.FileOutputStream(workfile); KeywordExpansionContext keywordExpansionContext = new KeywordExpansionContext(outputStream, workfile, mergedInfo.getLogfileInfo(), mergedInfo.getLogfileInfo().getRevisionInformation().getRevisionIndex(mergedInfo.getDefaultRevisionString()), "", dirManagerProxy.getAppendedPath(), dirManagerProxy.getProjectProperties()); KeywordManagerFactory.getInstance().getKeywordManager().expandKeywords(buffer, keywordExpansionContext); } catch (QVCSException e) { QWinUtility.logProblem(Level.WARNING, Utility.expandStackTraceToString(e)); } finally { if (outputStream != null) { outputStream.close(); } } } else { try { outputStream = new java.io.FileOutputStream(workfile); Utility.writeDataToStream(buffer, outputStream); } finally { if (outputStream != null) { outputStream.close(); } } } } catch (java.io.IOException e) { QWinUtility.logProblem(Level.WARNING, Utility.expandStackTraceToString(e)); } } protected void writeConflictFile(MergedInfoInterface mergedInfo, String conflictFileType, String workfileBase, byte[] buffer) { java.io.FileOutputStream outputStream = null; try { String fileExtension = Utility.getFileExtension(mergedInfo.getShortWorkfileName()); String fullWorkfileName = constructFullWorkfileName(mergedInfo, workfileBase); int indexOfExtension = fullWorkfileName.lastIndexOf("."); String constructedFileName = fullWorkfileName.substring(0, indexOfExtension) + "." + conflictFileType + "." + fileExtension; WorkFile workfile = new WorkFile(constructedFileName); if (!mergedInfo.getWorkfileExists()) { createWorkfileDirectory(mergedInfo); } if (workfile.exists()) { workfile.setReadWrite(); } try { outputStream = new java.io.FileOutputStream(workfile); Utility.writeDataToStream(buffer, outputStream); } finally { if (outputStream != null) { outputStream.close(); } } } catch (java.io.IOException e) { QWinUtility.logProblem(Level.WARNING, Utility.expandStackTraceToString(e)); } } private String constructFullWorkfileName(MergedInfoInterface mergedInfo, String workfileBase) { String fullWorkfileName = workfileBase + File.separator + mergedInfo.getArchiveDirManager().getAppendedPath() + File.separator + mergedInfo.getShortWorkfileName(); return fullWorkfileName; } }