diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsOperatorWorker.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsOperatorWorker.java index b59ac3c12..799abcf17 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsOperatorWorker.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsOperatorWorker.java @@ -10,7 +10,9 @@ import com.fr.report.entity.VcsEntity; import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; import com.fr.workspace.server.vcs.VcsOperator; +import com.fr.workspace.server.vcs.v2.VcsTaskResult; +import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import java.util.ArrayList; import java.util.List; @@ -26,7 +28,7 @@ import java.util.concurrent.ExecutionException; public class VcsOperatorWorker { private int count = 0; - private static final int FREQ = 5; + private static final int FREQ = 6; private String successStr; @@ -102,21 +104,16 @@ public class VcsOperatorWorker { * * @param vcsEntities 需要还原的版本 */ - public void batchRestore(List vcsEntities) { - List failedList = new ArrayList<>(); - startProcess(vcsEntities, failedList, (vcsEntity, operator) -> { + public void batchRestore(List vcsEntities, VcsTableOperatorListener listener) { + VcsProcessFailedWrapper wrapper = new VcsProcessFailedWrapper(); + startProcess(vcsEntities, wrapper, (vcsEntity, operator) -> { String fileName = vcsEntity.getFilename(); - boolean result = true; - try { - operator.restoreVersion(fileName); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - result = false; + VcsTaskResult result = operator.restoreVersion(fileName); + if (!result.isSuccess()) { + wrapper.addFailedEntity(vcsEntity); } - if (!result) { - failedList.add(fileName+PREFIX+vcsEntity.getVersion()+TAIL); - } - }); + return result; + }, listener); } @@ -126,25 +123,21 @@ public class VcsOperatorWorker { * @param vcsEntities 需要删除的版本 * @param all 是否需要删除所有版本 */ - public void batchDelete(List vcsEntities, boolean all) { - List failedList = new ArrayList<>(); - startProcess(vcsEntities, failedList, (vcsEntity, operator) -> { + public void batchDelete(List vcsEntities, boolean all, VcsTableOperatorListener listener) { + VcsProcessFailedWrapper wrapper = new VcsProcessFailedWrapper(); + startProcess(vcsEntities, wrapper, (vcsEntity, operator) -> { String fileName = vcsEntity.getFilename(); - boolean result = true; - try { - if (all) { - operator.deleteVersionForRecycle(fileName); - } else { - operator.deleteVersion(fileName, vcsEntity.getVersion()); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - result = false; + VcsTaskResult result; + if (all) { + result = operator.deleteVersionForRecycle(fileName); + } else { + result = operator.deleteVersion(fileName, vcsEntity.getVersion(), VcsEntity.CommitType.TYPE_DEFAULT); } - if (!result) { - failedList.add(fileName+PREFIX+vcsEntity.getVersion()+TAIL); + if (!result.isSuccess()) { + wrapper.addFailedEntity(vcsEntity); } - }); + return result; + }, listener); } @@ -153,9 +146,9 @@ public class VcsOperatorWorker { * * @param entity VcsEntity */ - public void doDelete(VcsEntity entity) { + public void doDelete(VcsEntity entity, VcsTableOperatorListener listener) { String fileName = entity.getFilename(); - start4Single(entity, (vcsEntity, operator) -> operator.deleteVersionForRecycle(fileName), fileName + everyFailedStr); + start4Single(entity, (vcsEntity, operator) -> operator.deleteVersionForRecycle(fileName), fileName + everyFailedStr, listener); } /** @@ -163,12 +156,11 @@ public class VcsOperatorWorker { * * @param entity 版本 */ - public void deleteTargetVersion(VcsEntity entity) { + public void deleteTargetVersion(VcsEntity entity, VcsTableOperatorListener listener) { String fileName = entity.getFilename(); int version = entity.getVersion(); - start4Single(entity, (vcsEntity, operator) -> { - operator.deleteVersion(fileName, version); - }, fileName + everyFailedStr); + VcsEntity.CommitType commitType = entity.getCommitType(); + start4Single(entity, (vcsEntity, operator) -> operator.deleteVersion(fileName, version, commitType), fileName + everyFailedStr, listener); } @@ -177,16 +169,17 @@ public class VcsOperatorWorker { * * @param entity 版本 */ - public void updateEntityAnnotation(VcsEntity entity) { + public void updateEntityAnnotation(VcsEntity entity, VcsTableOperatorListener listener) { start4Single(entity, (vcsEntity, operator) -> { operator.updateVersion(entity); - }, everyFailedStr); + return new VcsTaskResult(true); + }, everyFailedStr, listener); } - private void startProcess(List vcsEntities, List failedList, VcsWorkerOperator workerOperator) { + private void startProcess(List vcsEntities, VcsProcessFailedWrapper wrapper, VcsWorkerOperator workerOperator, VcsTableOperatorListener listener) { try { dialog.getProgressBar().setMaximum(vcsEntities.size()); - start4Batch(vcsEntities, failedList, workerOperator); + start4Batch(vcsEntities, wrapper, workerOperator, listener); dialog.showDialog(); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); @@ -202,13 +195,15 @@ public class VcsOperatorWorker { return (count > FREQ && count % FREQ == 0) || count < FREQ; } - private void start4Single(VcsEntity entity, VcsWorkerOperator vcsWorkerOperator, String failedTip) { + private void start4Single(VcsEntity entity, VcsWorkerOperator vcsWorkerOperator, String failedTip, VcsTableOperatorListener listener) { new SwingWorker() { @Override protected void done() { try { if (!get()) { - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), failedTip); + FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(DesignerContext.getDesignerFrame()), failedTip); + } else { + listener.updateUI(); } } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); @@ -218,16 +213,16 @@ public class VcsOperatorWorker { protected Boolean doInBackground() throws Exception { try { VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class); - vcsWorkerOperator.process(entity, operator); + VcsTaskResult result = vcsWorkerOperator.process(entity, operator); + return result.isSuccess(); } catch (Exception e) { return false; } - return true; } }.execute(); } - private void start4Batch(List vcsEntities, List failedList, VcsWorkerOperator workerOperator) { + private void start4Batch(List vcsEntities, VcsProcessFailedWrapper wrapper, VcsWorkerOperator workerOperator, VcsTableOperatorListener listener) { new SwingWorker() { @Override protected Boolean doInBackground() throws Exception { @@ -239,7 +234,7 @@ public class VcsOperatorWorker { publish(count); } } - return failedList.isEmpty(); + return wrapper.isAllSuccess(); } @Override protected void process(List chunks) { @@ -249,7 +244,9 @@ public class VcsOperatorWorker { protected void done() { dialog.closeDialog(); try { + List failedList = wrapper.getDetailFailedList(); showErrorDetailPane(get(), failedList, failedList.size(), vcsEntities.size() - failedList.size()); + listener.updateUI(wrapper); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } @@ -286,6 +283,6 @@ public class VcsOperatorWorker { * @param vcsEntity 版本 * @param operator 操作类 */ - void process(VcsEntity vcsEntity, VcsOperator operator) throws Exception; + VcsTaskResult process(VcsEntity vcsEntity, VcsOperator operator) throws Exception; } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsProcessFailedWrapper.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsProcessFailedWrapper.java new file mode 100644 index 000000000..0a257ce2e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsProcessFailedWrapper.java @@ -0,0 +1,60 @@ +package com.fr.design.mainframe.vcs; + +import com.fr.report.entity.VcsEntity; + +import java.util.ArrayList; +import java.util.List; + +/** + * 版本管理处理失败列表的包装类 + * + * @author Destiny.Lin + * @since 11.0 + * Created on 2023/7/28 + */ +public class VcsProcessFailedWrapper { + private static final String PREFIX = "(v."; + private static final String TAIL = ")"; + + private List failedList = new ArrayList<>(); + + + /** + * 添加处理失败的VcsEntity + * + * @param entity entity + */ + public void addFailedEntity(VcsEntity entity) { + failedList.add(entity); + } + + + /** + * 获取用于展示的详细失败信息列表 + */ + public List getDetailFailedList() { + List detailList = new ArrayList<>(); + for (VcsEntity entity : failedList) { + detailList.add(entity.getFilename()+PREFIX+entity.getVersion()+TAIL); + } + return detailList; + } + + /** + * 获取处理失败的vcsEntity的名称列表 + */ + public List getFailedNameList() { + List detailList = new ArrayList<>(); + for (VcsEntity entity : failedList) { + detailList.add(entity.getFilename()); + } + return detailList; + } + + /** + * 处理是否全部成功 + */ + public boolean isAllSuccess() { + return failedList.isEmpty(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableOperatorListener.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableOperatorListener.java index 831efc85e..a6f19572e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableOperatorListener.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableOperatorListener.java @@ -15,5 +15,18 @@ public interface VcsTableOperatorListener { /** * 处理操作 */ - void doOperator(List entityList); + default void doOperator(List entityList){} + + /** + * 更新界面 + */ + default void updateUI(){} + + + /** + * 根据处理失败的内容来更新界面 + * + * @param wrapper 失败内容 + */ + default void updateUI(VcsProcessFailedWrapper wrapper){} } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java index 49054f651..07007604d 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java @@ -22,6 +22,7 @@ import com.fr.log.FineLoggerFactory; import com.fr.plugin.context.PluginContext; import com.fr.plugin.manage.PluginManager; import com.fr.report.entity.VcsEntity; +import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; @@ -64,6 +65,8 @@ public class VcsHelper implements JTemplateActionListener { private final static String VCS_PLUGIN_ID = "com.fr.plugin.vcs.v10"; private final static String VCS_FILE_SLASH = "/"; private final static String SERVICE_NAME_MOVE = "moveVcs"; + private static final String VCS_VERSIONS = "reportlets_versions"; + private static final String VERSION_MARK = ".v"; private static final VcsHelper INSTANCE = new VcsHelper(); private static ScheduledExecutorService saveSchedule; @@ -398,4 +401,14 @@ public class VcsHelper implements JTemplateActionListener { public boolean checkAutoSaveSupport() { return VcsConfigManager.getInstance().isUseAutoSave() && !VcsHelper.getInstance().isLegacyMode(); } + + /** + * 获取文件路径 + * + * @param entity + * @return + */ + public String getFilePath(VcsEntity entity) { + return StableUtils.pathJoin(VCS_VERSIONS, entity.getFilename() + VERSION_MARK + entity.getVersion()); + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java index ef84c059e..98e7bae07 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java @@ -10,6 +10,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.vcs.VcsOperatorWorker; import com.fr.design.mainframe.vcs.TableEntity; import com.fr.design.mainframe.vcs.TableValueOperator; +import com.fr.design.mainframe.vcs.VcsProcessFailedWrapper; import com.fr.design.mainframe.vcs.VcsTableEntity; import com.fr.design.mainframe.vcs.VcsTableOperatorListener; import com.fr.report.entity.VcsEntity; @@ -165,7 +166,12 @@ public class RecyclePane extends AbstractSupportSelectTablePane fireListener(new VcsResponseListener() { @Override public void doAfterChooseYes(List selectList) { - VcsOperatorWorker.createDeleteWorker().batchDelete(selectList, isNeedDeleteAllVersion()); + VcsOperatorWorker.createDeleteWorker(). batchDelete(selectList, isNeedDeleteAllVersion(), new VcsTableOperatorListener() { + @Override + public void updateUI(VcsProcessFailedWrapper wrapper) { + updateVcsUI(wrapper); + } + }); } }, true); } @@ -182,7 +188,12 @@ public class RecyclePane extends AbstractSupportSelectTablePane fireListener(new VcsResponseListener() { @Override public void doAfterChooseYes(List selectList) { - VcsOperatorWorker.createRestoreWorker().batchRestore(selectList); + VcsOperatorWorker.createRestoreWorker().batchRestore(selectList, new VcsTableOperatorListener() { + @Override + public void updateUI(VcsProcessFailedWrapper wrapper) { + updateVcsUI(wrapper); + } + }); } }, false); } @@ -215,15 +226,17 @@ public class RecyclePane extends AbstractSupportSelectTablePane JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (selVal == JOptionPane.YES_OPTION) { - tableEntities = model.getList().stream().filter(tableEntity -> !tableEntity.isSelect()).collect(Collectors.toList()); - model.setList(new ArrayList<>(tableEntities)); - model.fireTableDataChanged(); listener.doAfterChooseYes(selectList); - fireVcsListener(model.getList()); } } } + private void updateVcsUI(VcsProcessFailedWrapper wrapper) { + tableEntities = model.getList().stream().filter(tableEntity -> !tableEntity.isSelect() || wrapper.getFailedNameList().contains(tableEntity.getFilename())).collect(Collectors.toList()); + model.setList(new ArrayList<>(tableEntities)); + model.fireTableDataChanged(); + fireVcsListener(model.getList()); + } /** * 显示弹窗 diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java index 354e02bd5..9efb268a0 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java @@ -10,6 +10,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.vcs.VcsOperatorWorker; import com.fr.design.mainframe.vcs.VcsTableEntity; +import com.fr.design.mainframe.vcs.VcsTableOperatorListener; import com.fr.design.mainframe.vcs.common.VcsCloseTemplateHelper; import com.fr.file.FileNodeFILE; import com.fr.file.filetree.FileNode; @@ -117,11 +118,15 @@ public class VcsCenterPane extends VcsNewPane { JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (selVal == JOptionPane.YES_OPTION) { - VcsOperatorWorker.createDeleteWorker().doDelete(entity); - removeTarget((VcsTableEntity) o); - model.fireTableRowsDeleted(row, row); - model.removeRow(row); - model.fireTableDataChanged(); + VcsOperatorWorker.createDeleteWorker().doDelete(entity, new VcsTableOperatorListener() { + @Override + public void updateUI() { + removeTarget((VcsTableEntity) o); + model.fireTableRowsDeleted(row, row); + model.removeRow(row); + model.fireTableDataChanged(); + } + }); } } } @@ -164,10 +169,13 @@ public class VcsCenterPane extends VcsNewPane { return entity.getFilename()+Toolkit.i18nText("Fine-Design_Vcs_Version_Tips"); } }; - pane.addVcsListener(entities -> { - if (entities.size() == 0) { - model.getList().remove(o); - model.fireTableDataChanged(); + pane.addVcsListener(new VcsTableOperatorListener() { + @Override + public void doOperator(List entityList) { + if (entities.size() == 0) { + model.getList().remove(o); + model.fireTableDataChanged(); + } } }); VcsCloseTemplateHelper.checkTemplateSavedAndShowVcsNewPane(path, VcsCloseTemplateHelper.isCurrentEditing(path), getDialog(), pane); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java index 638bc3a59..b924228fd 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java @@ -11,15 +11,18 @@ import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.vcs.TableValueOperator; import com.fr.design.mainframe.vcs.VcsOperatorWorker; import com.fr.design.mainframe.vcs.VcsTableEntity; +import com.fr.design.mainframe.vcs.VcsTableOperatorListener; import com.fr.design.mainframe.vcs.common.VcsCacheFileNodeFile; import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.file.FileNodeFILE; import com.fr.file.filetree.FileNode; +import com.fr.io.utils.ResourceIOUtils; import com.fr.report.entity.VcsEntity; import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; import com.fr.workspace.server.vcs.VcsFileUtils; import com.fr.workspace.server.vcs.VcsOperator; +import com.fr.workspace.server.vcs.v2.VcsTaskResult; import javax.swing.Icon; import javax.swing.JComponent; @@ -30,6 +33,7 @@ import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; +import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; @@ -51,6 +55,7 @@ public class VcsNewPane extends RecyclePane { protected static int EDIT_COL = 4; + private static final String PATH = "path"; private static final int DOUBLE_CLICK_COUNT = 2; protected VcsOperatorPane operatorPane; @@ -170,28 +175,42 @@ public class VcsNewPane extends RecyclePane { private void restoreEntity(VcsEntity entity) { - new SwingWorker() { + new SwingWorker() { @Override - protected Void doInBackground() throws Exception { + protected VcsTaskResult doInBackground() throws Exception { + String path = VcsHelper.getInstance().getFilePath(entity); + if (!ResourceIOUtils.exist(path)) { + return new VcsTaskResult(false, new FileNotFoundException()); + } //step1.设置还原的用户名 entity.setUsername(VcsHelper.getInstance().getCurrentUsername()); //step2.rollback到指定版本 WorkContext.getCurrent().get(VcsOperator.class).rollbackTo(entity); - return null; + //最里面的文件系统的write会吞异常,这边就一直默认成功吧,日志里会体现失败的情况 + return new VcsTaskResult(true); } @Override protected void done() { - //step3.如果原来原模板已经打开则关闭原模板,打开rollback后的新模板 - List> templateList = HistoryTemplateListCache.getInstance().getHistoryList(); - for (JTemplate template : templateList) { - if (StringUtils.equals(filePath, template.getPath())) { - MultiTemplateTabPane.getInstance().setIsCloseCurrent(HistoryTemplateListCache.getInstance().isCurrentEditingFile(filePath)); - MultiTemplateTabPane.getInstance().closeFormat(template); - MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(template); - break; + try { + VcsTaskResult result = get(); + if (result.isSuccess()) { + //step3.如果原来原模板已经打开则关闭原模板,打开rollback后的新模板 + List> templateList = HistoryTemplateListCache.getInstance().getHistoryList(); + for (JTemplate template : templateList) { + if (StringUtils.equals(filePath, template.getPath())) { + MultiTemplateTabPane.getInstance().setIsCloseCurrent(HistoryTemplateListCache.getInstance().isCurrentEditingFile(filePath)); + MultiTemplateTabPane.getInstance().closeFormat(template); + MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(template); + break; + } + } + DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(filePath, false))); + } else { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Warning_Template_Do_Not_Exsit")); } + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); } - DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(filePath, false))); } }.execute(); } @@ -213,10 +232,14 @@ public class VcsNewPane extends RecyclePane { JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (selVal == JOptionPane.YES_OPTION) { - model.fireTableRowsDeleted(row, row); - model.removeRow(row); - model.fireTableDataChanged(); - VcsOperatorWorker.createDeleteWorker().deleteTargetVersion(entity); + VcsOperatorWorker.createDeleteWorker().deleteTargetVersion(entity, new VcsTableOperatorListener() { + @Override + public void updateUI() { + model.fireTableRowsDeleted(row, row); + model.removeRow(row); + model.fireTableDataChanged(); + } + }); fireVcsListener(model.getList()); } } @@ -337,9 +360,13 @@ public class VcsNewPane extends RecyclePane { @Override public void doOK() { entity.setCommitMsg(getMsgTestArea().getText()); - VcsOperatorWorker.createUpdateWorker().updateEntityAnnotation(entity); - setVisible(false); - model.fireTableDataChanged(); + VcsOperatorWorker.createUpdateWorker().updateEntityAnnotation(entity, new VcsTableOperatorListener() { + @Override + public void updateUI() { + setVisible(false); + model.fireTableDataChanged(); + } + }); } }; dialog.setVisible(true);