package com.fr.start; import com.fr.common.report.ReportState; import com.fr.common.util.Collections; import com.fr.design.RestartHelper; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; import com.fr.env.detect.base.DetectorBridge; import com.fr.env.detect.bean.DetectorResult; import com.fr.env.detect.bean.DetectorStatus; import com.fr.env.detect.bean.DetectorType; import com.fr.env.detect.ui.DetectorErrorDialog; import com.fr.exit.DesignerExiter; import com.fr.general.IOUtils; import com.fr.io.utils.ResourceIOUtils; import com.fr.log.FineLoggerFactory; import com.fr.process.engine.core.CarryMessageEvent; import com.fr.process.engine.core.FineProcessContext; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.lifecycle.ErrorType; import com.fr.stable.lifecycle.ErrorTypeHelper; import com.fr.stable.lifecycle.FineLifecycleFatalError; import com.fr.stable.project.ProjectConstants; import javax.swing.JOptionPane; import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @author hades * @version 10.0 * Created by hades on 2020/3/16 */ public class LifecycleFatalErrorHandler { private static final LifecycleFatalErrorHandler INSTANCE = new LifecycleFatalErrorHandler(); private Map map = new HashMap<>(); private LifecycleFatalErrorHandler() { map.put(ErrorTypeHelper.FINEDB, FineDBHandler.SELF); } public static LifecycleFatalErrorHandler getInstance() { return INSTANCE; } public void handle(FineLifecycleFatalError fatal) { SplashContext.getInstance().hide(); FineProcessContext.getParentPipe().fire(new CarryMessageEvent(ReportState.STOP.getValue())); Handler handler = map.get(fatal.getErrorType()); if (handler == null) { handler = DefaultHandler.SELF; } handler.handle(fatal); } interface Handler { void handle(FineLifecycleFatalError error); } /** * finedb处理 */ enum FineDBHandler implements Handler { /** * 自检测 */ SELF { final EnumMap solutionMap = new EnumMap<>(DetectorType.class); { solutionMap.put(DetectorType.FINE_DB_LOCKED, "Fine-Design_Error_Finedb_Dirty_Backup_Reset"); solutionMap.put(DetectorType.FINE_DB_PERMISSION, "Fine-Design_Error_Finedb_Permission_Backup_Reset"); solutionMap.put(DetectorType.FINE_DB_DIRTY, "Fine-Design_Error_Finedb_Dirty_Backup_Reset"); } @Override public void handle(FineLifecycleFatalError fatal) { Stream resultStream = DetectorBridge.getInstance().detect(fatal); List results = resultStream .filter((e) -> e.getStatus() == DetectorStatus.EXCEPTION) .collect(Collectors.toList()); String showText = generateShowText(results); // 如果还是异常,则抛出预期外的错误 if (StringUtils.isEmpty(showText)) { DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); DetectorErrorDialog errorDialog = new DetectorErrorDialog(designerFrame, results); errorDialog.setVisible(true); return; } StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.FINEDB_PROBLEM.getId(), DesignerErrorMessage.FINEDB_PROBLEM.getMessage(), fatal.getMessage()); FineLoggerFactory.getLogger().error(DesignerErrorMessage.FINEDB_PROBLEM.getId() + ": " + DesignerErrorMessage.FINEDB_PROBLEM.getMessage()); int result = FineJOptionPane.showOptionDialog(null, showText, Toolkit.i18nText("Fine-Design_Basic_Error_Tittle"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, IOUtils.readIcon("com/fr/design/images/error/error2.png"), new Object[] {Toolkit.i18nText("Fine-Design_Basic_Reset"), Toolkit.i18nText("Fine-Design_Basic_Cancel")}, null); if (result == JOptionPane.YES_OPTION) { boolean success = false; try { ResourceIOUtils.copy(StableUtils.pathJoin(ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.FINE_DB_NAME), StableUtils.pathJoin(ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.FINE_DB_BAK_NAME)); success = ResourceIOUtils.delete(StableUtils.pathJoin(ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.FINE_DB_NAME)); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); afterBackupFailed(); } if (!success) { afterBackupFailed(); } else { RestartHelper.restart(); } } else { DesignerExiter.getInstance().execute(); } } /** * 生成展示信息 */ private String generateShowText(List results) { String showText = StringUtils.EMPTY; if (Collections.isEmpty(results)) { showText = Toolkit.i18nText("Fine-Design_Error_Finedb_Backup_Reset"); } else { for (DetectorResult result : results) { DetectorType type = result.getType(); String solutionLocale = solutionMap.get(type); if (StringUtils.isNotEmpty(solutionLocale)) { showText = Toolkit.i18nText(solutionLocale); break; } } } return showText; } private void afterBackupFailed() { FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Error_Finedb_Backup_Reset_Result", ResourceIOUtils.getRealPath(StableUtils.pathJoin(ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.FINE_DB_NAME))), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE); DesignerExiter.getInstance().execute(); } } } /** * 默认处理 */ enum DefaultHandler implements Handler { /** * 自处理 */ SELF { @Override public void handle(FineLifecycleFatalError fatal) { DesignerExiter.getInstance().exit(fatal); } } } }