Browse Source

Merge branch 'feature/x' of https://code.fineres.com/scm/~fly.li/design into feature/x

feature/x
fly.li 2 years ago
parent
commit
abe6787d74
  1. 8
      build.gradle
  2. 35
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  3. 14
      designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java
  4. 12
      designer-base/src/main/java/com/fr/design/data/datapane/connect/SshPane.java
  5. 5
      designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java
  6. 4
      designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java
  7. 22
      designer-base/src/main/java/com/fr/design/formula/FormulaPane.java
  8. 17
      designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java
  9. 26
      designer-base/src/main/java/com/fr/design/gui/frpane/JTreeControlPane.java
  10. 158
      designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java
  11. 40
      designer-base/src/main/java/com/fr/design/gui/frpane/tree/layer/config/LayerDataControlPane.java
  12. 2
      designer-base/src/main/java/com/fr/design/gui/style/ReportBackgroundSpecialPane.java
  13. 5
      designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java
  14. 5823
      designer-base/src/main/java/com/fr/design/gui/syntax/ui/rsyntaxtextarea/modes/FormulaTokenMaker.java
  15. 2
      designer-base/src/main/java/com/fr/design/javascript/JavaScriptActionPane.java
  16. 26
      designer-base/src/main/java/com/fr/design/login/socketio/LoginAuthServer.java
  17. 6
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  18. 11
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  19. 9
      designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ColorBackgroundQuickPane.java
  20. 2
      designer-base/src/main/java/com/fr/design/mainframe/widget/accessibles/AccessibleTreeModelEditor.java
  21. 5
      designer-base/src/main/java/com/fr/design/mainframe/widget/wrappers/TreeModelWrapper.java
  22. 45
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzer.java
  23. 131
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java
  24. 12
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerAdvice.java
  25. 23
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerListener.java
  26. 91
      designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAssemblyFactory.java
  27. 23
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/DBMonitorAdvice.java
  28. 46
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/FaultToleranceAdvice.java
  29. 31
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/FocusAdvice.java
  30. 157
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/MonitorAdvice.java
  31. 49
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/PerformancePointAdvice.java
  32. 36
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/TimeAdvice.java
  33. 25
      designer-base/src/main/java/com/fr/design/record/analyzer/advice/TrackAdvice.java
  34. 42
      designer-base/src/main/java/com/fr/design/startup/Install4jStartupNotificationProvider.java
  35. 4
      designer-base/src/main/java/com/fr/design/style/color/ColorCell.java
  36. 13
      designer-base/src/main/java/com/fr/design/style/color/NewColorSelectBox.java
  37. 12
      designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java
  38. 27
      designer-base/src/main/java/com/fr/env/utils/WorkspaceUtils.java
  39. 111
      designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java
  40. 34
      designer-base/src/main/java/com/fr/file/FILEChooserPane.java
  41. 2
      designer-base/src/main/java/com/fr/start/BaseDesigner.java
  42. 14
      designer-base/src/main/java/com/fr/start/event/LazyStartupEvent.java
  43. 8
      designer-base/src/main/resources/com/fr/design/gui/syntax/ui/rsyntaxtextarea/modes/FormulaTokenMaker.flex
  44. 139
      designer-base/src/test/java/com/fr/design/record/analyzer/BytebuddyRedefineTest.java
  45. 50
      designer-base/src/test/java/com/fr/design/record/analyzer/TestCallableAdvice.java
  46. 15
      designer-base/src/test/java/com/fr/design/record/analyzer/TestCallableHelper.java
  47. 11
      designer-base/src/test/java/com/fr/design/record/analyzer/TestClass.java
  48. 29
      designer-base/src/test/java/com/fr/design/record/analyzer/TestModifyReturnAdvice.java
  49. 19
      designer-base/src/test/java/com/fr/design/record/analyzer/TestThrowExceptionAdvice.java
  50. 37
      designer-base/src/test/java/com/fr/design/record/analyzer/TestTransferValueAdvice.java
  51. 2
      designer-chart/src/main/java/com/fr/design/module/ChartHyperlinkGroup.java
  52. 2
      designer-chart/src/main/java/com/fr/van/chart/designer/component/background/VanChartBackgroundPaneWithThemeStyle.java
  53. 15
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopDialog.java
  54. 39
      designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java
  55. 4
      designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java
  56. 7
      designer-realize/src/main/java/com/fr/design/mainframe/HyperlinkGroupPaneActionImpl.java
  57. 4
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java
  58. 3
      designer-realize/src/main/java/com/fr/design/webattr/WriteWebSettingPane.java
  59. 14
      designer-realize/src/main/java/com/fr/design/widget/ui/TreeComboBoxEditorDefinePane.java
  60. 20
      designer-realize/src/main/java/com/fr/design/widget/ui/TreeEditorDefinePane.java
  61. 38
      designer-realize/src/main/java/com/fr/start/MainDesigner.java
  62. 2
      designer-realize/src/main/java/com/fr/start/SplashContext.java
  63. 24
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java
  64. 102
      designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java
  65. 9
      designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java
  66. 8
      designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java
  67. 30
      designer-realize/src/main/java/com/fr/start/module/optimized/BaseDBActivator4Designer.java
  68. 27
      designer-realize/src/main/java/com/fr/start/module/optimized/ConfigurationActivator4Designer.java
  69. 32
      designer-realize/src/main/java/com/fr/start/module/optimized/ReportBaseActivator4Designer.java
  70. 42
      designer-realize/src/main/java/com/fr/start/module/optimized/TenantDBAdapter4Designer.java

8
build.gradle

@ -67,10 +67,10 @@ allprojects {
implementation 'com.fr.third:jxbrowser:6.23'
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation 'com.fr.third:jxbrowser-v7:7.15'
implementation 'com.fr.third:jxbrowser-mac-v7:7.15'
implementation 'com.fr.third:jxbrowser-win64-v7:7.15'
implementation 'com.fr.third:jxbrowser-swing-v7:7.15'
implementation 'com.fr.third:jxbrowser-v7:7.22'
implementation 'com.fr.third:jxbrowser-mac-v7:7.22'
implementation 'com.fr.third:jxbrowser-win64-v7:7.22'
implementation 'com.fr.third:jxbrowser-swing-v7:7.22'
implementation 'com.fr.third.server:servlet-api:3.0'
implementation 'org.swingexplorer:swexpl:2.0.1'
implementation 'org.swingexplorer:swag:1.0'

35
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -214,6 +214,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private boolean useOptimizedUPM4Adapter;
private boolean propertiesUsable;
/**
* DesignerEnvManager.
*/
@ -442,12 +444,35 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private static File envFile = null;
private File getEnvFile() {
checkDebugStart();
if (envFile == null) {
envFile = new File(ProductConstants.getEnvHome() + File.separator + ProductConstants.APP_NAME + "Env.xml");
}
return envFile;
}
/**
* 在VM options里加入-Ddebug=true激活
*/
private static void checkDebugStart() {
if (ComparatorUtils.equals("true", System.getProperty("debug"))) {
setDebugEnv();
}
}
/**
* 端口改一下环境配置文件改一下便于启动两个设计器进行对比调试
*/
private static void setDebugEnv() {
DesignUtils.setPort(DesignerPort.getInstance().getDebugMessagePort());
DesignerEnvManager.setEnvFile(new File(StableUtils.pathJoin(
ProductConstants.getEnvHome(),
ProductConstants.APP_NAME + "Env_debug.xml"
)));
}
/**
* 是否启用了https
*
@ -676,6 +701,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.useOptimizedUPM4Adapter = useOptimizedUPM4Adapter;
}
public boolean isPropertiesUsable() {
return this.propertiesUsable;
}
public void setPropertiesUsable(boolean propertiesUsable) {
this.propertiesUsable = propertiesUsable;
}
/**
* 知否自动备份
*
@ -1900,6 +1933,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.setEmbedServerLazyStartup(reader.getAttrAsBoolean("embedServerLazyStartup", false));
this.setShowTemplateMissingPlugin(reader.getAttrAsBoolean("showTemplateMissingPlugin", true));
this.setUseOptimizedUPM4Adapter(reader.getAttrAsBoolean("useOptimizedUPM4Adapter", SupportOSImpl.MACOS_12_VERSION_ADAPTER.support()));
this.setPropertiesUsable(reader.getAttrAsBoolean("propertiesUsable", false));
this.setShowServerDatasetAuthTip(reader.getAttrAsBoolean("showServerDatasetAuthTip", true));
this.setLayoutTemplateStyle(reader.getAttrAsInt("layoutTemplateStyle", LAYOUT_TEMPLATE_SIMPLE_STYLE));
}
@ -2178,6 +2212,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
writer.attr("layoutTemplateStyle", this.getLayoutTemplateStyle());
writer.attr("showServerDatasetAuthTip", this.isShowServerDatasetAuthTip());
writer.attr("useOptimizedUPM4Adapter", this.isUseOptimizedUPM4Adapter());
writer.attr("propertiesUsable", this.isPropertiesUsable());
writer.end();
}

14
designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java

@ -10,11 +10,10 @@ import com.fr.design.editlock.EditLockUtils;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UILockButton;
import com.fr.file.ConnectionConfig;
import com.fr.general.ComparatorUtils;
import com.fr.report.LockItem;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.connection.DBConnectAuth;
import com.fr.report.LockItem;
import javax.swing.SwingUtilities;
import java.awt.Dimension;
@ -96,6 +95,7 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
continue;
}
Connection connection = mgr.getConnection(conName);
// nameList依赖items方法初始化,父类ItemEditableComboBoxPanel里异步执行item方法
filterConnection(connection, conName, nameList);
}
@ -140,12 +140,10 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel {
} else {
String s = DesignerEnvManager.getEnvManager().getRecentSelectedConnection();
if (StringUtils.isNotBlank(s)) {
for (int i = 0; i < this.getConnectionSize(); i++) {
String t = this.getConnection(i);
if (ComparatorUtils.equals(s, t)) {
this.setSelectedItem(s);
break;
}
// 之前的写法有多线程问题,nameList异步尚未初始化完成的时候,这里可能无法匹配设置数据连接名称,导致DBTableDataPane打开后连接面板空白
// 这里的需求无非是设置上一次使用的数据连接,做个简单检查这个连接是否存在即可,存在就设置
if (ConnectionConfig.getInstance().getConnection(s) != null) {
this.setSelectedItem(s);
}
}
// alex:如果这个ComboBox还是没有选中,那么选中第一个

12
designer-base/src/main/java/com/fr/design/data/datapane/connect/SshPane.java

@ -7,6 +7,7 @@ import com.fr.data.security.ssh.SshException;
import com.fr.data.security.ssh.SshType;
import com.fr.data.security.ssh.impl.KeyVerifySsh;
import com.fr.data.security.ssh.impl.NormalSsh;
import com.fr.data.security.ssl.SslUtils;
import com.fr.design.border.UITitledBorder;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicPane;
@ -25,7 +26,6 @@ import com.fr.file.FILE;
import com.fr.file.FILEChooserPane;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.third.guava.collect.HashBiMap;
import javax.swing.ImageIcon;
@ -131,7 +131,7 @@ public class SshPane extends BasicPane {
fileChooserButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
FILEChooserPane fileChooser = FILEChooserPane.getInstanceWithDesignatePath(ProjectConstants.RESOURCES_NAME, new ChooseFileFilter(true));
FILEChooserPane fileChooser = FILEChooserPane.getInstanceWithDesignatePath(SslUtils.PREFIX, new ChooseFileFilter(true), SslUtils.CERTIFICATES);
int type = fileChooser.showOpenDialog(SshPane.this, StringUtils.EMPTY);
if (type == FILEChooserPane.OK_OPTION) {
final FILE file = fileChooser.getSelectedFILE();
@ -142,6 +142,7 @@ public class SshPane extends BasicPane {
}
}
fileChooser.removeAllFilter();
fileChooser.removeTopPath();
}
});
}
@ -241,7 +242,6 @@ public class SshPane extends BasicPane {
public static class KeyFileUITextField extends UITextField {
private static final Pattern ERROR_START = Pattern.compile("^([/\\\\.]+).*");
private static final Pattern MUTI_DOT = Pattern.compile("\\.+");
private static final String PREFIX = ProjectConstants.RESOURCES_NAME + "/";
private static final String UPPER = "..";
public KeyFileUITextField(int columns) {
@ -283,7 +283,7 @@ public class SshPane extends BasicPane {
public String getText() {
// 获取的时候,不为空,给他加上前缀就好了,否则还是空
if (!StringUtils.isEmpty(super.getText())) {
return PREFIX + super.getText();
return SslUtils.PREFIX + super.getText();
}
return StringUtils.EMPTY;
}
@ -291,8 +291,8 @@ public class SshPane extends BasicPane {
@Override
public void setText(String text) {
// 设置的时候,不为空,说明文件指定了(文件需要是resource下),替换掉前缀
if (!StringUtils.isEmpty(text) && text.startsWith(PREFIX)) {
super.setText(text.replaceFirst(PREFIX, ""));
if (!StringUtils.isEmpty(text) && text.startsWith(SslUtils.PREFIX)) {
super.setText(text.replaceFirst(SslUtils.PREFIX, ""));
} else {
super.setText(text);
}

5
designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java

@ -4,6 +4,7 @@ import com.fr.data.impl.JDBCDatabaseConnection;
import com.fr.data.security.ssl.Ssl;
import com.fr.data.security.ssl.SslException;
import com.fr.data.security.ssl.SslType;
import com.fr.data.security.ssl.SslUtils;
import com.fr.data.security.ssl.impl.NormalSsl;
import com.fr.design.border.UITitledBorder;
import com.fr.design.constants.UIConstants;
@ -21,7 +22,6 @@ import com.fr.file.FILE;
import com.fr.file.FILEChooserPane;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
@ -148,7 +148,7 @@ public class SslPane extends BasicPane {
@Override
public void actionPerformed(ActionEvent e) {
FILEChooserPane fileChooser = FILEChooserPane.getInstanceWithDesignatePath(ProjectConstants.RESOURCES_NAME, new ChooseFileFilter(true));
FILEChooserPane fileChooser = FILEChooserPane.getInstanceWithDesignatePath(SslUtils.PREFIX, new ChooseFileFilter(true), SslUtils.CERTIFICATES);
int type = fileChooser.showOpenDialog(SslPane.this, StringUtils.EMPTY);
if (type == FILEChooserPane.OK_OPTION) {
final FILE file = fileChooser.getSelectedFILE();
@ -159,6 +159,7 @@ public class SslPane extends BasicPane {
}
}
fileChooser.removeAllFilter();
fileChooser.removeTopPath();
}
}
}

4
designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java vendored

@ -1,8 +1,6 @@
package com.fr.design.env;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
@ -10,8 +8,8 @@ import com.fr.stable.project.ProjectConstants;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLableReader;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.engine.exception.MainVersionNotMatchException;
import java.io.File;
import java.util.Properties;

22
designer-base/src/main/java/com/fr/design/formula/FormulaPane.java

@ -14,6 +14,7 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.DialogActionListener;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.gui.autocomplete.AutoCompleteExtraRefreshComponent;
@ -63,6 +64,7 @@ import com.fr.stable.script.Node;
import com.fr.stable.script.Tiny;
import com.fr.stable.script.TinyHunter;
import java.awt.Window;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
@ -736,6 +738,13 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Formula_Definition");
}
public BasicDialog showLargeWindow(Window window, DialogActionListener l) {
BasicDialog basicDialog = super.showWindowWithCustomSize(window, l, new Dimension(900, 600));
basicDialog.setMinimumSize(new Dimension(900, 600));
basicDialog.setResizable(true);
return basicDialog;
}
/**
* Populate
*/
@ -1102,6 +1111,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void initGroupTypeModel() {
functionTypeListModel.addElement(FunctionConstants.COMMON);
functionTypeListModel.addElement(FunctionConstants.NEW);
for (int i = 0; i < FunctionConstants.EMBFUNCTIONS.length; i++) {
functionTypeListModel.addElement(FunctionConstants.EMBFUNCTIONS[i]);
}
@ -1186,9 +1196,6 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
descriptionTextArea = new UITextArea();
descriptionTextArea.setPreferredSize(new Dimension(350, 200));
UIScrollPane desScrollPane = new UIScrollPane(descriptionTextArea);
desScrollPane.setBorder(null);
this.add(this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Formula_Description") + ":", desScrollPane), BorderLayout.EAST);
descriptionTextArea.setBackground(Color.white);
descriptionTextArea.setLineWrap(true);
descriptionTextArea.setWrapStyleWord(true);
@ -1256,12 +1263,13 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
private void initVariablesTree() {
JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane();
// vairable.
variablesTree = new JTree();
UIScrollPane variablesTreePane = new UIScrollPane(variablesTree);
variablesTreePane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC));
this.add(this.createNamePane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Variables") + ":", variablesTreePane), BorderLayout.CENTER);
panel.add(this.createNamePane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Variables") + ":", variablesTreePane), BorderLayout.WEST);
variablesTree.setRootVisible(false);
variablesTree.setShowsRootHandles(true);
variablesTree.addMouseListener(applyTextMouseListener);
@ -1269,7 +1277,11 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula {
initDescriptionTextArea();
UIScrollPane desScrollPane = new UIScrollPane(descriptionTextArea);
desScrollPane.setBorder(null);
panel.add(this.createNamePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaPane_Formula_Description") + ":", desScrollPane), BorderLayout.CENTER);
initVariablesTreeSelectionListener();
this.add(panel,BorderLayout.CENTER);
}
private void initComponents() {

17
designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java

@ -5,10 +5,19 @@ import com.fr.function.AVERAGE;
import com.fr.function.CHAR;
import com.fr.function.COUNT;
import com.fr.function.DATE;
import com.fr.function.ENBYSTRNUM;
import com.fr.function.EOMONTH;
import com.fr.function.GCD;
import com.fr.function.GETCHARNUM;
import com.fr.function.ISWORKDAY;
import com.fr.function.LCM;
import com.fr.function.MAX;
import com.fr.function.MIDCHAR;
import com.fr.function.MIN;
import com.fr.function.NUMTOZH;
import com.fr.function.RANGE;
import com.fr.function.SUM;
import com.fr.function.TEXTGETNUM;
import com.fr.function.TIME;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils;
@ -48,6 +57,7 @@ public final class FunctionConstants {
public static NameAndTypeAndFunctionList[] EMBFUNCTIONS = getEmbededFunctionListArray();
public static FunctionGroup ALL = getAllFunctionGroup();
public static List<String> abandonFormulas = Arrays.asList("CIRCULAR", "CROSSLAYERTOTAL", "HIERARCHY", "LAYERTOTAL");
public static NameAndFunctionList NEW = getNewFunctionList();
static {
loadEmbededFunctions();
@ -276,6 +286,13 @@ public final class FunctionConstants {
});
}
private static NameAndFunctionList getNewFunctionList() {
return new NameAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_New"), new Function[]{
new EOMONTH(), new NUMTOZH(), new MIDCHAR(), new ISWORKDAY(), new ENBYSTRNUM(), new TEXTGETNUM(),
new GETCHARNUM(), new GCD(), new LCM()
});
}
private static NameAndTypeAndFunctionList[] getEmbededFunctionListArray() {
return new NameAndTypeAndFunctionList[] {
new NameAndTypeAndFunctionList(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FormulaD_Math_&_Trig"), Function.MATH),

26
designer-base/src/main/java/com/fr/design/gui/frpane/JTreeControlPane.java

@ -42,14 +42,10 @@ public class JTreeControlPane extends ControlPane {
private JTree tree;
private DefaultTreeModel defaultTreeModel;
boolean isEditor = false;
private UICheckBox isPerformanceFirst;
public JTreeControlPane(NameableCreator[] creators, BasicBeanPane updatePane, boolean isEditor) {
public JTreeControlPane(NameableCreator[] creators, BasicBeanPane updatePane) {
this.initComponents(creators, updatePane);
this.isEditor = isEditor;
}
private void initComponents(NameableCreator[] creators, BasicBeanPane updatePane) {
@ -120,11 +116,7 @@ public class JTreeControlPane extends ControlPane {
if (obj instanceof TreeNodeAttr[]) {
treeNodeAttr = ((TreeNodeAttr[]) obj);
isPerformanceFirst.setSelected(false);
} else if (obj instanceof TreeEditor) {
TreeEditor treeEditor = (TreeEditor) obj;
treeNodeAttr = treeEditor.getTreeNodeAttr();
isPerformanceFirst.setSelected(treeEditor.isPerformanceFirst());
} else if (obj instanceof TreeNodeWrapper) {
}else if (obj instanceof TreeNodeWrapper) {
treeNodeAttr = ((TreeNodeWrapper) obj).getTreeNodeAttrs();
isPerformanceFirst.setSelected(((TreeNodeWrapper) obj).isPerformanceFirst());
}
@ -146,18 +138,8 @@ public class JTreeControlPane extends ControlPane {
}
public NameObject update() {
if (isEditor) {
TreeEditor treeEditor = new TreeEditor();
treeEditor.setTreeNodeAttr(updateTreeNodeAttr());
treeEditor.setPerformanceFirst(isPerformanceFirst.isSelected());
return new NameObject("tree", treeEditor);
} else {
TreeNodeWrapper treeNodeWrapper = new TreeNodeWrapper(isPerformanceFirst.isSelected(), updateTreeNodeAttr());
return new NameObject("tree", treeNodeWrapper);
}
TreeNodeWrapper treeNodeWrapper = new TreeNodeWrapper(isPerformanceFirst.isSelected(), updateTreeNodeAttr());
return new NameObject("tree", treeNodeWrapper);
}
public TreeNodeAttr[] updateTreeNodeAttr() {

158
designer-base/src/main/java/com/fr/design/gui/frpane/TreeSettingPane.java

@ -26,12 +26,18 @@ import java.awt.event.ItemListener;
import java.util.Arrays;
public class TreeSettingPane extends BasicPane implements DataCreatorUI {
/**
* 普通分层构建方式
*/
private JTreeControlPane controlPane;
/**
* 自动构建方式
*/
private JTreeAutoBuildPane autoBuildPane;
/**
* 新的分层构建方式
* 急速分层构建方式
*/
private LayerDataControlPane layerDataControlPane;
@ -43,15 +49,15 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
private static final long serialVersionUID = 1762889323082827111L;
private String[] buildWay = new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_DataTable_Build"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Auto_Build"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Layer_Build")};
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Auto_Build"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Layer_Build")};
public TreeSettingPane(boolean isEditor) {
this.initComponents(isEditor);
public TreeSettingPane() {
this.initComponents();
}
private void initComponents(boolean isEditor) {
private void initComponents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel buildWayPanel= FRGUIPaneFactory.createMediumHGapFlowInnerContainer_M_Pane();
JPanel buildWayPanel = FRGUIPaneFactory.createMediumHGapFlowInnerContainer_M_Pane();
buildWayPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
UILabel buildWayLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Build_Way") + " :");
buildWayPanel.add(buildWayLabel);
@ -65,8 +71,8 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
});
buildWayPanel.add(buildBox);
controlPane = new JTreeControlPane(new NameableCreator[] { treeNode },
new TreeDataCardPane(), isEditor);
controlPane = new JTreeControlPane(new NameableCreator[]{treeNode},
new TreeDataCardPane());
autoBuildPane = new JTreeAutoBuildPane();
layerDataControlPane = new LayerDataControlPane();
this.add(buildWayPanel, BorderLayout.NORTH);
@ -108,87 +114,14 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
}
NameableCreator treeNode = new NameObjectCreator(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Gradation"),
"/com/fr/design/images/data/source/jdbcTableData.png",
TreeNodeAttr.class);
/**
*
* @param treeEditor
*/
public void populate(TreeEditor treeEditor) {
boolean isAutoBuild = treeEditor.isAutoBuild();
TreeAttr treeAttr = treeEditor.getTreeAttr();
if (treeAttr != null) {
NameObject no = new NameObject("name", treeEditor);
controlPane.populate(no);
}
if (isAutoBuild) {
buildBox.setSelectedIndex(1);
TableDataDictionary dictionary = treeEditor.getDictionary();
autoBuildPane.populate(dictionary);
} else if (treeEditor.isFastLayerBuild()) {
buildBox.setSelectedIndex(0);
java.util.List<LayerConfig> layerConfigList = treeEditor.getLayerConfigs();
LayerConfig[] layerConfigs = new LayerConfig[layerConfigList.size()];
int i = 0;
for (LayerConfig layerConfig : layerConfigList) {
layerConfigs[i++] = layerConfig;
}
this.layerDataControlPane.populate(new NameObject("Tree Layer Data", layerConfigs));
} else {
buildBox.setSelectedIndex(2);
}
}
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Gradation"),
"/com/fr/design/images/data/source/jdbcTableData.png",
TreeNodeAttr.class);
/**
* 视图树的update
* @return
*/
public TreeEditor updateTreeEditor() {
// NameObject no = this.controlPane.update();
// if (no != null) {
// return ((TreeEditor) no.getObject());
// }
//
// return null;
TreeEditor te = new TreeEditor();
if (buildBox.getSelectedIndex() == 1) {
TableDataDictionary dictionary = this.autoBuildPane.update();
te.setAutoBuild(true);
te.setFastLayerBuild(false);
te.setDictionary(dictionary);
te.setNodeOrDict(dictionary);
} else if (buildBox.getSelectedIndex() == 2) {
te.setAutoBuild(false);
te.setFastLayerBuild(false);
NameObject no = this.controlPane.update();
if (no != null) {
TreeEditor editor = (TreeEditor) no.getObject();
te.setAllowBlank(editor.isAllowBlank());
te.setEnabled(editor.isEnabled());
te.setDirectEdit(editor.isDirectEdit());
te.setErrorMessage(editor.getErrorMessage());
te.setWidgetName(editor.getWidgetName());
te.setVisible(editor.isVisible());
te.setWaterMark(editor.getWaterMark());
te.setRemoveRepeat(editor.isRemoveRepeat());
te.setTreeAttr(editor.getTreeAttr());
te.setTreeNodeAttr(editor.getTreeNodeAttr());
te.setNodeOrDict(editor.getTreeNodeAttr());
te.setPerformanceFirst(editor.isPerformanceFirst());
}
} else {
LayerConfig[] configs = (LayerConfig[]) layerDataControlPane.update().getObject();
te.setAutoBuild(false);
te.setFastLayerBuild(true);
te.setLayerConfigs(Arrays.asList(configs));
}
return te;
}
/**
* 树节点属性的update
*
* @return
*/
public Object updateTreeNodeAttrs() {
@ -207,64 +140,19 @@ public class TreeSettingPane extends BasicPane implements DataCreatorUI {
}
/**
* 下拉树的update
* @return
*/
public TreeComboBoxEditor updateTreeComboBox() {
TreeComboBoxEditor tcb = new TreeComboBoxEditor();
if (buildBox.getSelectedIndex() == 1) {
TableDataDictionary dictionary = this.autoBuildPane.update();
tcb.setAutoBuild(true);
tcb.setFastLayerBuild(false);
tcb.setDictionary(dictionary);
tcb.setNodeOrDict(dictionary);
} else if (buildBox.getSelectedIndex() == 2) {
tcb.setAutoBuild(false);
tcb.setFastLayerBuild(false);
NameObject no = this.controlPane.update();
if (no != null) {
if (no.getObject() instanceof TreeComboBoxEditor) {
return (TreeComboBoxEditor) no.getObject();
}
TreeEditor editor = (TreeEditor) no.getObject();
tcb.setAllowBlank(editor.isAllowBlank());
tcb.setEnabled(editor.isEnabled());
tcb.setDirectEdit(editor.isDirectEdit());
tcb.setErrorMessage(editor.getErrorMessage());
tcb.setWidgetName(editor.getWidgetName());
tcb.setVisible(editor.isVisible());
tcb.setWaterMark(editor.getWaterMark());
tcb.setRemoveRepeat(editor.isRemoveRepeat());
tcb.setTreeAttr(editor.getTreeAttr());
tcb.setTreeNodeAttr(editor.getTreeNodeAttr());
tcb.setNodeOrDict(editor.getTreeNodeAttr());
tcb.setPerformanceFirst(editor.isPerformanceFirst());
}
}else {
LayerConfig[] configs = (LayerConfig[]) layerDataControlPane.update().getObject();
tcb.setAutoBuild(false);
tcb.setFastLayerBuild(true);
tcb.setLayerConfigs(Arrays.asList(configs));
}
return tcb;
}
/**
*
* @param nodeOrDict
*/
public void populate(Object nodeOrDict) {
if(nodeOrDict instanceof TreeNodeAttr[] || nodeOrDict instanceof TreeNodeWrapper) {
if (nodeOrDict instanceof TreeNodeAttr[] || nodeOrDict instanceof TreeNodeWrapper) {
buildBox.setSelectedIndex(2);
NameObject no = new NameObject("name", nodeOrDict);
controlPane.populate(no);
} else if(nodeOrDict instanceof TableDataDictionary) {
} else if (nodeOrDict instanceof TableDataDictionary) {
buildBox.setSelectedIndex(1);
autoBuildPane.populate((TableDataDictionary)nodeOrDict);
} else if (nodeOrDict instanceof NameObject) {
autoBuildPane.populate((TableDataDictionary) nodeOrDict);
} else if (nodeOrDict instanceof LayerConfig[]) {
buildBox.setSelectedIndex(0);
layerDataControlPane.populate((NameObject) nodeOrDict);
layerDataControlPane.populate((LayerConfig[]) nodeOrDict);
}
}
}

40
designer-base/src/main/java/com/fr/design/gui/frpane/tree/layer/config/LayerDataControlPane.java

@ -179,7 +179,7 @@ public class LayerDataControlPane extends ControlPane {
public void actionPerformed(ActionEvent e) {
// TODO remove tree node
int val = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?",
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (val != JOptionPane.OK_OPTION) {
return;
}
@ -193,36 +193,32 @@ public class LayerDataControlPane extends ControlPane {
}
}
public void populate(NameObject nameObject) {
public void populate(LayerConfig[] layerConfigs) {
// 重新添加tree节点的时候需要remove掉原来的所有子节点
((DefaultMutableTreeNode) defaultTreeModel.getRoot()).removeAllChildren();
if (BEAN_NAME.equals(nameObject.getName())) {
Object obj = nameObject.getObject();
LayerConfig[] layerConfigs = null;
if (obj instanceof LayerConfig[]) {
layerConfigs = ((LayerConfig[]) obj);
}
if (layerConfigs == null) {
return;
}
int count = layerConfigs == null ? 0 : layerConfigs.length;
//将树的层次一层一层的加上去
DefaultMutableTreeNode node4root = (DefaultMutableTreeNode) defaultTreeModel.getRoot();
for (int i = 0; i < count; i++) {
int count = layerConfigs.length;
//将树的层次一层一层的加上去
DefaultMutableTreeNode node4root = (DefaultMutableTreeNode) defaultTreeModel.getRoot();
for (int i = 0; i < count; i++) {
DefaultMutableTreeNode node4add = new DefaultMutableTreeNode(
DefaultMutableTreeNode node4add = new DefaultMutableTreeNode(
new NameObject(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Gradation") + (i + 1), layerConfigs[i].clone()));
node4root.add(node4add);
node4root = node4add;
}
defaultTreeModel.reload();
expandAll(tree, true);
tree.setSelectionRow(0);
node4root.add(node4add);
node4root = node4add;
}
defaultTreeModel.reload();
expandAll(tree, true);
tree.setSelectionRow(0);
}
public NameObject update() {
public LayerConfig[] update() {
return new NameObject(BEAN_NAME, updateLayerDatas());
return updateLayerDatas();
}
private LayerConfig[] updateLayerDatas() {

2
designer-base/src/main/java/com/fr/design/gui/style/ReportBackgroundSpecialPane.java

@ -29,7 +29,7 @@ public class ReportBackgroundSpecialPane extends BackgroundPane {
protected BackgroundQuickPane[] supportKindsOfBackgroundUI() {
NullBackgroundQuickPane nullBackgroundPane = new NullBackgroundQuickPane();
ColorBackgroundQuickPane colorBackgroundPane = new ColorBackgroundQuickPane();
ColorBackgroundQuickPane colorBackgroundPane = new ColorBackgroundQuickPane(true);
colorBackgroundPane.registerChangeListener(new UIObserverListener() {
@Override
public void doChange() {

5
designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java

@ -58,8 +58,9 @@ public class TextFormatPane extends AbstractBasicStylePane implements GlobalName
private static final Integer[] TYPES = new Integer[]{
FormatContents.NULL, FormatContents.NUMBER,
FormatContents.CURRENCY, FormatContents.PERCENT,
FormatContents.SCIENTIFIC, FormatContents.DATE,
FormatContents.TIME, FormatContents.TEXT};
FormatContents.THOUSANDTHS, FormatContents.SCIENTIFIC,
FormatContents.DATE, FormatContents.TIME,
FormatContents.TEXT};
private static final Integer[] DATE_TYPES = new Integer[]{FormatContents.NULL, FormatContents.DATE, FormatContents.TIME};

5823
designer-base/src/main/java/com/fr/design/gui/syntax/ui/rsyntaxtextarea/modes/FormulaTokenMaker.java

File diff suppressed because it is too large Load Diff

2
designer-base/src/main/java/com/fr/design/javascript/JavaScriptActionPane.java

@ -42,7 +42,7 @@ public abstract class JavaScriptActionPane extends UIComboBoxPane<JavaScript> {
protected List<FurtherBasicBeanPane<? extends JavaScript>> initPaneList() {
List<FurtherBasicBeanPane<? extends JavaScript>> paneList = new ArrayList<FurtherBasicBeanPane<? extends JavaScript>>();
// JS脚本,表单提交,提交入库,流程管理,发送邮件. 703中去掉表单提交和流程管理
paneList.add(new JavaScriptImplPane(getDefaultArgs()));
paneList.add(new JavaScriptImplPane(getDefaultArgs(),true));
// paneList.add(new FormSubmitJavaScriptPane(this));
contentDBManiPane = new ArrayList();
contentDBManiPane.add(createDBManipulationPane());

26
designer-base/src/main/java/com/fr/design/login/socketio/LoginAuthServer.java

@ -1,5 +1,6 @@
package com.fr.design.login.socketio;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.DesignerEnvManager;
import com.fr.design.login.DesignerLoginType;
import com.fr.design.login.bean.BBSAccountLogin;
@ -11,7 +12,11 @@ import com.fr.third.socketio.Configuration;
import com.fr.third.socketio.SocketIOClient;
import com.fr.third.socketio.SocketIOServer;
import com.fr.third.socketio.listener.DataListener;
import java.net.URLDecoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Lanlan
@ -19,9 +24,11 @@ import java.net.URLDecoder;
* Created by Lanlan on 2021/6/3
*/
public class LoginAuthServer {
private AtomicBoolean started = new AtomicBoolean(false);
private SocketIOServer server;
private static final String HOSTNAME = "localhost";
private static final int PORT = 41925;
@ -47,6 +54,23 @@ public class LoginAuthServer {
}
public void start() {
// 只运行一次,不在乎成不成功
if (started.compareAndSet(false, true)) {
asyncStart();
}
}
public void asyncStart() {
ExecutorService asyncService = Executors.newSingleThreadExecutor(new NamedThreadFactory(LoginAuthServer.class.getName(), true));
asyncService.submit(this::compatibleStart);
asyncService.shutdown();
}
@Deprecated
public void compatibleStart() {
try {
server.start();
} catch (Exception e) {

6
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java

@ -4,6 +4,7 @@
package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fr.base.OptimizeUtil;
import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
@ -42,6 +43,7 @@ import com.fr.design.lock.LockInfoDialog;
import com.fr.event.EventDispatcher;
import com.fr.exception.DecryptTemplateException;
import com.fr.exception.TplLockedException;
import com.fr.exit.ConfigToPropMigrator;
import com.fr.exit.DesignerExiter;
import com.fr.file.FILE;
import com.fr.file.FILEFactory;
@ -1071,6 +1073,10 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
DesignerEnvManager.getEnvManager().setLastEastRegionContainerWidth(
EastRegionContainerPane.getInstance().getContainerWidth());
OptimizeUtil.open(() -> {
ConfigToPropMigrator.getInstance().execute();
});
DesignerEnvManager.getEnvManager().saveXMLFile();
}

11
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -1016,6 +1016,17 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
}
public byte[] exportData() throws Exception {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
BaseBook target = getTarget();
if (target != null) {
target.export(outputStream);
return outputStream.toByteArray();
}
}
return new byte[0];
}
protected boolean export() throws Exception {
return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(getEditingFILE()));

9
designer-base/src/main/java/com/fr/design/mainframe/backgroundpane/ColorBackgroundQuickPane.java

@ -16,10 +16,9 @@ public class ColorBackgroundQuickPane extends BackgroundQuickPane {
private NewColorSelectBox colorSelectBox;
public ColorBackgroundQuickPane() {
public ColorBackgroundQuickPane(boolean supportTransparent) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
colorSelectBox = new NewColorSelectBox(100) {
colorSelectBox = new NewColorSelectBox(100, supportTransparent) {
@Override
public boolean shouldResponseChangeListener() {
// ColorBackgroundQuickPane注册监听器ChangeListenerImpl的逻辑不能丢,因为里面有修改字段backgroundChange的逻辑.
@ -33,6 +32,10 @@ public class ColorBackgroundQuickPane extends BackgroundQuickPane {
this.add(colorSelectBox, BorderLayout.NORTH);
}
public ColorBackgroundQuickPane() {
this(false);
}
public void populateBean(Background background) {
ColorBackground colorBackgroud = (ColorBackground) background;
populateColor(colorBackgroud.getColor());

2
designer-base/src/main/java/com/fr/design/mainframe/widget/accessibles/AccessibleTreeModelEditor.java

@ -23,7 +23,7 @@ public class AccessibleTreeModelEditor extends UneditableAccessibleEditor {
@Override
protected void showEditorPane() {
if (treeSettingPane == null) {
treeSettingPane = new TreeSettingPane(false);
treeSettingPane = new TreeSettingPane();
}
BasicDialog dlg = treeSettingPane.showWindow(SwingUtilities.getWindowAncestor(this));
treeSettingPane.populate(getValue());

5
designer-base/src/main/java/com/fr/design/mainframe/widget/wrappers/TreeModelWrapper.java

@ -6,8 +6,7 @@ import com.fr.data.impl.TreeNodeWrapper;
import com.fr.design.Exception.ValidationException;
import com.fr.design.designer.properties.Decoder;
import com.fr.design.designer.properties.Encoder;
import com.fr.general.NameObject;
import com.fr.form.ui.tree.LayerConfig;
import com.fr.stable.StringUtils;
public class TreeModelWrapper implements Encoder, Decoder {
@ -22,7 +21,7 @@ public class TreeModelWrapper implements Encoder, Decoder {
} else if (v instanceof TreeNodeWrapper) {
TreeNodeAttr[] treeNodeAttrs = ((TreeNodeWrapper) v).getTreeNodeAttrs();
return TemplateUtils.render(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Total_N_Grade"), new String[]{"N"}, new String[]{treeNodeAttrs.length + ""});
} else if (v instanceof NameObject) {
} else if (v instanceof LayerConfig[]) {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_DataTable_Build");
} else {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Auto_Build");

45
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzer.java

@ -0,0 +1,45 @@
package com.fr.design.record.analyzer;
import com.fr.design.record.analyzer.advice.TimeAdvice;
import com.fr.design.record.analyzer.advice.TrackAdvice;
import com.fr.record.analyzer.AnalyzerConfiguration;
import com.fr.record.analyzer.AnalyzerUnit;
import com.fr.record.analyzer.Assistant;
import com.fr.record.analyzer.Metrics;
import com.fr.record.analyzer.Track;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.stable.ArrayUtils;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.description.type.TypeDescription;
import com.fr.third.net.bytebuddy.dynamic.DynamicType;
import com.fr.third.net.bytebuddy.matcher.ElementMatchers;
import com.fr.third.net.bytebuddy.utility.JavaModule;
/**
* created by Harrison on 2022/03/08
**/
public class DesignerAnalyzer {
private static final AnalyzerUnit ANALYZER = new AnalyzerUnit();
public static synchronized void init(AnalyzerAssemblyFactory factory, AnalyzerConfiguration... configurations) {
AnalyzerAssemblyFactory redefineFactory = factory.prepare(DesignerAssemblyFactory.getInstance());
AnalyzerConfiguration defaultConfiguration = AnalyzerConfiguration.create(new Assistant() {
@Override
public DynamicType.Builder<?> supply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
return builder
.visit(Advice.to(TimeAdvice.class).on(ElementMatchers.isAnnotatedWith(Metrics.class)))
.visit(Advice.to(TrackAdvice.class).on(ElementMatchers.isAnnotatedWith(Track.class)));
}
});
AnalyzerConfiguration[] allConfigurations = ArrayUtils.add(configurations, defaultConfiguration);
// 准备监听
ANALYZER.setAgentListener(new DesignerAnalyzerListener());
ANALYZER.init(redefineFactory, allConfigurations);
}
}

131
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerActivator.java

@ -0,0 +1,131 @@
package com.fr.design.record.analyzer;
import com.fr.base.OptimizeUtil;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.constants.DesignerLaunchStatus;
import com.fr.design.record.analyzer.advice.DBMonitorAdvice;
import com.fr.design.record.analyzer.advice.FaultToleranceAdvice;
import com.fr.design.record.analyzer.advice.FocusAdvice;
import com.fr.design.record.analyzer.advice.MonitorAdvice;
import com.fr.design.record.analyzer.advice.PerformancePointAdvice;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.intelli.metrics.Compute;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.PerformancePoint;
import com.fr.module.Activator;
import com.fr.module.extension.Prepare;
import com.fr.record.analyzer.AnalyzerConfiguration;
import com.fr.record.analyzer.AnalyzerKey;
import com.fr.record.analyzer.DBMetrics;
import com.fr.record.analyzer.FineAnalyzer;
import com.fr.record.analyzer.advice.AnalyzerAdviceKey;
import com.fr.record.analyzer.advice.FineAdviceAssistant;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.record.analyzer.configuration.FineAnalyzerAssemblyFactory;
import com.fr.stable.collections.CollectionUtils;
import com.fr.third.net.bytebuddy.matcher.ElementMatchers;
import com.fr.tolerance.FaultTolerance;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.ExecutorService;
/**
* created by Harrison on 2022/03/04
**/
public class DesignerAnalyzerActivator extends Activator implements Prepare {
@Override
public void start() {
OptimizeUtil.open(() -> {
AnalyzerAssemblyFactory basicFactory = createBasicFactory();
// 兼容逻辑
List<AnalyzerConfiguration> backwardsConfigurations = findMutableBackwards(AnalyzerKey.KEY);
if (!CollectionUtils.isEmpty(backwardsConfigurations)) {
// 直接初始化,不添加默认值,防止和下面的冲突
FineAnalyzer.initDirectly(basicFactory, backwardsConfigurations.toArray(new AnalyzerConfiguration[0]));
}
// 等页面完全打开后,再进行 retransform, 别影响了启动速度
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
ExecutorService es = newSingleThreadExecutor(new NamedThreadFactory("designer-analyzer", true));
try {
// 加入 retransform 部分的逻辑
List<FineAdviceAssistant> adviceConfigurations = findMutable(AnalyzerAdviceKey.KEY);
if (!CollectionUtils.isEmpty(adviceConfigurations)) {
AnalyzerConfiguration[] configurations = convertConfigurations(adviceConfigurations);
es.submit(() -> {
DesignerAnalyzer.init(basicFactory, configurations);
});
}
} finally {
es.shutdown();
}
}
});
});
}
@NotNull
private AnalyzerConfiguration[] convertConfigurations(List<FineAdviceAssistant> list) {
return list.stream()
.map(AnalyzerConfiguration::create)
.toArray(AnalyzerConfiguration[]::new);
}
@Override
public void stop() {
}
@Override
public void prepare() {
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(Focus.class),
FocusAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(Compute.class),
MonitorAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(DBMetrics.class),
DBMonitorAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(PerformancePoint.class),
PerformancePointAdvice.class
));
addMutable(AnalyzerAdviceKey.KEY, FineAdviceAssistant.create(
ElementMatchers.isAnnotatedWith(FaultTolerance.class),
FaultToleranceAdvice.class
));
}
private AnalyzerAssemblyFactory createBasicFactory() {
AnalyzerAssemblyFactory factory = findSingleton(AnalyzerAssemblyFactory.class);
FineAnalyzerAssemblyFactory basicFactory = new FineAnalyzerAssemblyFactory();
basicFactory.prepare(factory);
return basicFactory;
}
}

12
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerAdvice.java

@ -0,0 +1,12 @@
package com.fr.design.record.analyzer;
import com.fr.record.analyzer.advice.AnalyzerAdvice;
/**
* 仅作为标志
* 没有方法
*
* created by Harrison on 2022/03/04
**/
public interface DesignerAnalyzerAdvice extends AnalyzerAdvice {
}

23
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAnalyzerListener.java

@ -0,0 +1,23 @@
package com.fr.design.record.analyzer;
import com.fr.log.FineLoggerFactory;
import com.fr.third.net.bytebuddy.agent.builder.AgentBuilder;
import com.fr.third.net.bytebuddy.description.type.TypeDescription;
import com.fr.third.net.bytebuddy.dynamic.DynamicType;
import com.fr.third.net.bytebuddy.utility.JavaModule;
/**
* created by Harrison on 2022/03/08
**/
public class DesignerAnalyzerListener extends AgentBuilder.Listener.Adapter {
@Override
public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded, DynamicType dynamicType) {
FineLoggerFactory.getLogger().debug("Designer-Analyzer transform successfully:{}", typeDescription);
}
@Override
public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) {
FineLoggerFactory.getLogger().error("Designer-Analyzer transform error:" + typeName);
}
}

91
designer-base/src/main/java/com/fr/design/record/analyzer/DesignerAssemblyFactory.java

@ -0,0 +1,91 @@
package com.fr.design.record.analyzer;
import com.fr.record.analyzer.configuration.AnalyzerAssemblyFactory;
import com.fr.third.net.bytebuddy.agent.builder.AgentBuilder;
import java.util.List;
import java.util.Map;
/**
* 装配 Agent 为后置启动
* <p>必须在一个线程中处理 retransform 的事务否则会阻塞整个的线程导致效果不佳</p>
*
* created by Harrison on 2022/03/07
**/
public class DesignerAssemblyFactory implements AnalyzerAssemblyFactory<Void> {
/**
* 每次执行 1 class retransform
*/
private static final int FIXED_SIZE = 1;
/**
* 单位 ms
* 每次间隔 500 ms, 执行一次
*/
private static final int DELAY_INTERVAL = 500;
private final AgentBuilder.RedefinitionStrategy.BatchAllocator batchAllocator = AgentBuilder.RedefinitionStrategy.BatchAllocator.ForFixedSize.ofSize(FIXED_SIZE);
private final AgentBuilder.RedefinitionStrategy.Listener redefinitionListener = new DelayListener(DELAY_INTERVAL);
public static DesignerAssemblyFactory getInstance() {
return DesignerAssemblyFactoryHolder.INSTANCE;
}
private static class DesignerAssemblyFactoryHolder {
private static final DesignerAssemblyFactory INSTANCE = new DesignerAssemblyFactory();
}
@Override
public AnalyzerAssemblyFactory<Void> prepare(Void material) {
return this;
}
@Override
public AgentBuilder assembly(AgentBuilder raw) {
return raw.disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
// 每次只 transform 一部分否则会导致 UI 变慢
.with(batchAllocator)
.with(redefinitionListener)
.with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
.with(AgentBuilder.TypeStrategy.Default.REDEFINE);
}
private class DelayListener implements AgentBuilder.RedefinitionStrategy.Listener {
/**
* 单位 ms
*/
private final int interval;
public DelayListener(int interval) {
this.interval = interval;
}
/**
* 执行完后等待一段时间再执行
*/
@Override
public void onBatch(int index, List<Class<?>> batch, List<Class<?>> types) {
try {
Thread.sleep(interval);
} catch (Exception ignore) {
}
}
@Override
public Iterable<? extends List<Class<?>>> onError(int index, List<Class<?>> batch, Throwable throwable, List<Class<?>> types) {
return null;
}
@Override
public void onComplete(int amount, List<Class<?>> types, Map<List<Class<?>>, Throwable> failures) {
}
}
}

23
designer-base/src/main/java/com/fr/design/record/analyzer/advice/DBMonitorAdvice.java

@ -0,0 +1,23 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.general.data.DataModel;
import com.fr.measure.DBMeterFactory;
import com.fr.measure.metric.DBMetric;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
/**
* created by Harrison on 2022/03/07
**/
public class DBMonitorAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args) {
if (args.length > 1 && args[1] instanceof DataModel) {
DBMetric meter = ((DataModel) args[1]).getMetric();
DBMeterFactory.getMeter().record(meter);
}
}
}

46
designer-base/src/main/java/com/fr/design/record/analyzer/advice/FaultToleranceAdvice.java

@ -0,0 +1,46 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.record.analyzer.advice.AdviceContext;
import com.fr.record.analyzer.advice.DefaultAdviceCallable;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import com.fr.tolerance.FaultTolerance;
import com.fr.tolerance.FaultToleranceFactory;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
/**
* created by Harrison on 2022/03/07
**/
public class FaultToleranceAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static boolean onMethodEnter(@Advice.Local("context") AdviceContext adviceContext) throws Exception {
adviceContext = AdviceContext
.builder()
.onAdviceCall()
.build();
// 如果是切面调用,则忽视当前方法
return adviceContext.isOnAdviceCall();
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result,
@Advice.Local("context")AdviceContext adviceContext) throws Exception {
// 如果是切面调用,则忽视不继续 exit
if (adviceContext != null && adviceContext.isOnAdviceCall()) {
return;
}
FaultTolerance faultTolerance = method.getAnnotation(FaultTolerance.class);
Callable<Object> callable = new DefaultAdviceCallable<>(self, method, args);
result = FaultToleranceFactory.getInstance().getScene(faultTolerance.scene()).getProcessor().execute(self, callable, args);
}
}

31
designer-base/src/main/java/com/fr/design/record/analyzer/advice/FocusAdvice.java

@ -0,0 +1,31 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.FocusPoint;
import com.fr.intelli.record.FocusPolicy;
import com.fr.log.counter.DefaultLimitedMetric;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
/**
* created by Harrison on 2022/03/07
**/
public class FocusAdvice implements DesignerAnalyzerAdvice {
private static final String FOCUS_POINT_ID_PREFIX = "function_";
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.Origin Method method,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result) throws Exception {
if (FocusPolicy.IGNORE == result) {
return;
}
Focus focus = method.getAnnotation(Focus.class);
String id = FOCUS_POINT_ID_PREFIX + focus.id();
DefaultLimitedMetric.INSTANCE.submit(FocusPoint.create(id, focus.text(), focus.source()), id);
}
}

157
designer-base/src/main/java/com/fr/design/record/analyzer/advice/MonitorAdvice.java

@ -0,0 +1,157 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.general.GeneralUtils;
import com.fr.intelli.measure.Estimator;
import com.fr.intelli.metrics.Compute;
import com.fr.intelli.metrics.SupervisoryConfig;
import com.fr.intelli.record.Measurable;
import com.fr.intelli.record.MeasureObject;
import com.fr.intelli.record.MeasureUnit;
import com.fr.intelli.record.MetricRegistry;
import com.fr.log.FineLoggerFactory;
import com.fr.measure.DBMeterFactory;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.web.Session;
import com.fr.stable.web.SessionProvider;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import com.fr.web.core.SessionPoolManager;
import com.fr.web.session.SessionLocalManager;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* created by Harrison on 2022/03/07
**/
public class MonitorAdvice implements DesignerAnalyzerAdvice {
private static final Pattern P = Pattern.compile("-?\\d+");
private static final int MIN_ERROR_CODE = 10000000;
@Advice.OnMethodEnter
public static void onMethodEnter(@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Local("startTime") Long startTime,
@Advice.Local("registeredSession") Boolean registeredSession) {
startTime = (System.currentTimeMillis());
registeredSession = (findSessionAnnotation(method, args));
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Thrown(typing = Assigner.Typing.DYNAMIC) Exception e,
@Advice.Local("startTime") Long startTime,
@Advice.Local("registeredSession") Boolean registeredSession) throws Exception {
String error = StringUtils.EMPTY;
try {
if (e != null) {
try {
error = getErrorContent(e);
} catch (Exception ignore) {
}
}
} finally {
try {
if (self instanceof Measurable) {
long consume = System.currentTimeMillis() - startTime;
Compute once = method.getAnnotation(Compute.class);
Measurable measurable = (Measurable) self;
MeasureObject measureObject = MeasureObject.create();
recordMemory(once, measurable, measureObject);
recordSQL(once, measureObject);
measureObject.consume(consume);
measureObject.error(error);
String id = UUID.randomUUID().toString();
List<Object> newArgs = new ArrayList<>(Arrays.asList(args));
newArgs.add(id);
recordSQLDetail(id);
if (measurable instanceof Estimator) {
measurable.asyncDurable(measureObject, newArgs.toArray());
} else {
Object message = null;
try {
message = measurable.durableEntity(measureObject, newArgs.toArray());
} catch (Throwable throwable) {
FineLoggerFactory.getLogger().error(throwable.getMessage(), throwable);
}
if (message != null) {
MetricRegistry.getMetric().submit(message);
}
}
}
} catch (Exception ignore) {
//埋点信息入库失败应该不能影响业务流程
} finally {
if (registeredSession) {
// 如果上面记录了,这里就要释放
SessionLocalManager.releaseSession();
}
}
}
}
public static String getErrorContent(Exception e) {
int errorCode = GeneralUtils.objectToNumber(
extractCodeFromString(e.getMessage())
).intValue();
// 提取字符串中的第一个数字,最小的错误码为10000000
return e.getClass().getName() + ":" + (errorCode >= MIN_ERROR_CODE ? errorCode : StringUtils.EMPTY);
}
public static String extractCodeFromString(String errorMsg) {
Matcher m = P.matcher(errorMsg);
if (m.find()) {
return m.group();
}
return StringUtils.EMPTY;
}
public static void recordSQLDetail(String uuid) {
DBMeterFactory.getMeter().submit(uuid);
}
public static void recordSQL(Compute once, MeasureObject measureObject) {
if (SupervisoryConfig.getInstance().isEnableMeasureSql() && once.computeSql()) {
measureObject.sqlTime(SessionLocalManager.getSqlTime());
measureObject.sql(SessionLocalManager.getSql());
}
}
public static void recordMemory(Compute once, Measurable measurable, MeasureObject measureObject) {
if (SupervisoryConfig.getInstance().isEnableMeasureMemory() && once.computeMemory()) {
MeasureUnit unit = measurable.measureUnit();
measureObject.memory(unit.measureMemory());
}
}
public static boolean findSessionAnnotation(Method method, Object[] args) {
Annotation[][] all = method.getParameterAnnotations();
int len = ArrayUtils.getLength(args);
for (int i = 0; i < len; i++) {
Annotation[] current = all[i];
for (Annotation annotation : current) {
if (annotation.annotationType().equals(Session.class)) {
SessionLocalManager.setSession(
SessionPoolManager.getSessionIDInfor(GeneralUtils.objectToString(args[i]), SessionProvider.class));
return true;
}
}
}
return false;
}
}

49
designer-base/src/main/java/com/fr/design/record/analyzer/advice/PerformancePointAdvice.java

@ -0,0 +1,49 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.intelli.record.ConsumePoint;
import com.fr.intelli.record.MetricRegistry;
import com.fr.intelli.record.PerformancePoint;
import com.fr.intelli.record.PerformancePointRecord;
import com.fr.stable.StringUtils;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* created by Harrison on 2022/03/07
**/
public class PerformancePointAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodEnter
public static void onMethodEnter(@Advice.Local("startTime") Long startTime) {
startTime = (System.currentTimeMillis());
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Local("startTime") Long startTime) {
PerformancePoint point = method.getAnnotation(PerformancePoint.class);
String id = point.id();
long endTime = System.currentTimeMillis();
long consume = endTime - startTime;
if (self instanceof PerformancePointRecord) {
PerformancePointRecord measurable = (PerformancePointRecord) self;
List<Object> newArgs = new ArrayList<Object>(Arrays.asList(args));
ConsumePoint consumePoint = ConsumePoint.create(id, startTime, endTime, consume, point.source());
MetricRegistry.getMetric().submit(measurable.recordPoint(consumePoint, newArgs.toArray()));
} else {
if (StringUtils.isNotEmpty(id)) {
MetricRegistry.getMetric().submit(ConsumePoint.create(id, consume, point.source()));
}
}
}
}

36
designer-base/src/main/java/com/fr/design/record/analyzer/advice/TimeAdvice.java

@ -0,0 +1,36 @@
package com.fr.design.record.analyzer.advice;
import com.fr.design.record.analyzer.DesignerAnalyzerAdvice;
import com.fr.log.FineLoggerFactory;
import com.fr.record.analyzer.Metrics;
import com.fr.third.net.bytebuddy.asm.Advice;
import java.lang.reflect.Method;
/**
* created by Harrison on 2022/03/08
**/
public class TimeAdvice implements DesignerAnalyzerAdvice {
@Advice.OnMethodEnter
public static void onMethodEnter(@Advice.Local("startTime") Long startTime) {
startTime = (System.currentTimeMillis());
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.Origin Method method,
@Advice.Local("startTime") Long startTime) {
Metrics metrics = method.getAnnotation(Metrics.class);
Object prefix;
String description = metrics.description();
if ("".equals(description)) {
prefix = method.getDeclaringClass().getName() + "#" + method.getName();
} else {
prefix = description;
}
FineLoggerFactory.getLogger().info("{} took {} ms.", prefix, System.currentTimeMillis() - startTime);
}
}

25
designer-base/src/main/java/com/fr/design/record/analyzer/advice/TrackAdvice.java

@ -0,0 +1,25 @@
package com.fr.design.record.analyzer.advice;
import com.fr.intelli.record.MetricRegistry;
import com.fr.third.javax.persistence.Entity;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.util.List;
/**
* created by Harrison on 2022/03/08
**/
public class TrackAdvice {
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result) {
if (result != null) {
Class clazz = result.getClass();
if (clazz.getAnnotation(Entity.class) != null || result instanceof List) {
MetricRegistry.getMetric().submit(result);
}
}
}
}

42
designer-base/src/main/java/com/fr/design/startup/Install4jStartupNotificationProvider.java

@ -1,6 +1,10 @@
package com.fr.design.startup;
import com.install4j.api.launcher.StartupNotification;
import com.fr.invoke.Reflect;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author Starryi
@ -18,18 +22,30 @@ public class Install4jStartupNotificationProvider implements FineStartupNotifica
@Override
public void registerStartupListener(Listener listener) {
boolean supported = false;
try {
supported = Class.forName("com.install4j.api.launcher.StartupNotification") != null;
} catch (Throwable ignored) {}
if (supported) {
StartupNotification.registerStartupListener(new StartupNotification.Listener() {
@Override
public void startupPerformed(String parameters) {
listener.startupPerformed(parameters);
}
});
Class<?> StartupNotificationListenerClass = Reflect.on("com.install4j.api.launcher.StartupNotification$Listener").type();
if (StartupNotificationListenerClass == null) {
return;
}
ListenerHandler mHandler = new ListenerHandler(listener);
Object listenerCallbackInstance = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { StartupNotificationListenerClass }, mHandler);
Reflect.on("com.install4j.api.launcher.StartupNotification").call("registerStartupListener", listenerCallbackInstance);
}
private static class ListenerHandler implements InvocationHandler {
private final Listener listener;
public ListenerHandler(Listener listener) {
this.listener = listener;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (args[0] instanceof String) {
String parameters = (String) args[0];
listener.startupPerformed(parameters);
}
return null;
}
}
}

4
designer-base/src/main/java/com/fr/design/style/color/ColorCell.java

@ -100,11 +100,13 @@ public class ColorCell extends JComponent implements ColorSelectable {
if (e == null || e.getID() == MouseEvent.MOUSE_RELEASED) {
colorSelectable.setColor(this.getColor());
colorSelectable.colorSetted(this);
// 先添加最近使用
if (this.getColor() != null) {
int rgb = this.getColor().getRGB();
DesignerEnvManager.getEnvManager().getColorConfigManager().addToColorQueue(new Color(rgb));
}
// 这边会获取到最近使用颜色并更新 添加逻辑需要放到前面 否则不会及时更新
colorSelectable.colorSetted(this);
}
if (e != null) {

13
designer-base/src/main/java/com/fr/design/style/color/NewColorSelectBox.java

@ -20,13 +20,20 @@ public class NewColorSelectBox extends AbstractSelectBox<Color> implements UIObs
private static final long serialVersionUID = 2782150678943960557L;
private Color color;
private NewColorSelectPane colorPane = new NewColorSelectPane(false);
private NewColorSelectPane colorPane;
private UIObserverListener uiObserverListener;
private String newColorSelectBoxName = "";
private GlobalNameListener globalNameListener = null;
private boolean supportTransparent;
public NewColorSelectBox(int preferredWidth) {
initBox(preferredWidth);
this(preferredWidth, false);
}
public NewColorSelectBox(int preferredWidth, boolean supportTransparent) {
this.colorPane = new NewColorSelectPane(supportTransparent);
this.supportTransparent = supportTransparent;
initBox(preferredWidth);
iniListener();
}
@ -58,7 +65,7 @@ public class NewColorSelectBox extends AbstractSelectBox<Color> implements UIObs
*/
public JPanel initWindowPane(double preferredWidth) {
// 下拉的时候重新生成面板,以刷新最近使用颜色
colorPane = new NewColorSelectPane(false);
colorPane = new NewColorSelectPane(this.supportTransparent);
colorPane.setColor(this.getSelectObject());
colorPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {

12
designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java

@ -1,7 +1,6 @@
package com.fr.design.utils;
import com.fr.base.extension.FileExtension;
import com.fr.base.io.BaseBook;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.i18n.Toolkit;
@ -17,9 +16,9 @@ import com.fr.stable.CoreConstants;
import com.fr.stable.ProductConstants;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.lock.TplOperator;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import javax.swing.SwingWorker;
import java.io.OutputStream;
/**
* @author hades
@ -65,12 +64,7 @@ public class TemplateUtils {
if (!needOpen) {
// 从当前编辑模板中生成备份文件
JTemplate<?, ?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BaseBook target = template.getTarget();
if (target != null) {
target.export(outputStream);
content = outputStream.toByteArray();
}
content = template.exportData();
} else {
content = WorkContext.getWorkResource().readFully(oldPath);
}

27
designer-base/src/main/java/com/fr/env/utils/WorkspaceUtils.java vendored

@ -0,0 +1,27 @@
package com.fr.env.utils;
import com.fr.design.DesignerEnvManager;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.LocalDesignerWorkspaceInfo;
import com.fr.stable.StringUtils;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/3/10
*/
public class WorkspaceUtils {
private static final String SPECIFY_WORKSPACE = "fr.designer.workspace";
public static DesignerWorkspaceInfo getWorkspaceInfo() {
String workspacePath;
String current = DesignerEnvManager.getEnvManager().getCurEnvName();
if (StringUtils.isNotEmpty(workspacePath = System.getProperty(SPECIFY_WORKSPACE))) {
return LocalDesignerWorkspaceInfo.create(StringUtils.EMPTY, workspacePath);
} else {
return DesignerEnvManager.getEnvManager().getWorkspaceInfo(current);
}
}
}

111
designer-base/src/main/java/com/fr/exit/ConfigToPropMigrator.java

@ -0,0 +1,111 @@
package com.fr.exit;
import com.fr.config.dao.PropertiesConstants;
import com.fr.design.DesignerEnvManager;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.CommonUtils;
import com.fr.stable.StableUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
/**
* 设计器关闭前的配置缓存一份到Properties
*
* @author hades
* @version 11.0
* Created by hades on 2022/3/1
*/
public class ConfigToPropMigrator {
private static final String SELECT_FOR_ENTITY = "select id, value from fine_conf_entity";
private static final String SELECT_FOR_CLASSNAME = "select id, classname from fine_conf_classname";
private static final String SELECT_FOR_XML_ENTITY = "select id, value from fine_conf_xmlentity";
private static final ConfigToPropMigrator INSTANCE = new ConfigToPropMigrator();
public static ConfigToPropMigrator getInstance() {
return INSTANCE;
}
public void execute() {
if (WorkContext.getCurrent().isLocal()) {
String url = "jdbc:hsqldb:file://" + WorkContext.getCurrent().getPath() + "/" + ProjectConstants.EMBED_DB_DIRECTORY + "/finedb/db;hsqldb.tx=mvcc";
try {
Class.forName("com.fr.third.org.hsqldb.jdbcDriver");
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return ;
}
initDirectory();
try (Connection c = DriverManager.getConnection(url);
FileOutputStream entityOut = new FileOutputStream(PropertiesConstants.ENTITY_PROP_PATH);
FileOutputStream classHelperOut = new FileOutputStream(PropertiesConstants.CLASS_NAME_PROP_PATH);
FileOutputStream xmlEntityOut = new FileOutputStream(PropertiesConstants.XML_ENTITY_PROP_PATH)) {
processClassOrEntity(c, new Properties(), SELECT_FOR_ENTITY, entityOut);
processClassOrEntity(c, new Properties(), SELECT_FOR_CLASSNAME, classHelperOut);
processXmlEntity(c, new Properties(), xmlEntityOut);
DesignerEnvManager.getEnvManager().setPropertiesUsable(true);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
deletePropertiesCache();
}
}
}
private void initDirectory() {
File directory = new File(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), ProjectConstants.EMBED_DB_DIRECTORY, ProjectConstants.PROPERTIES_CACHE_FOR_CONFIG));
if (!directory.exists()) {
directory.mkdir();
}
}
private void processClassOrEntity(Connection c, Properties map, String sql, FileOutputStream outputStream) throws SQLException, IOException {
PreparedStatement query = c.prepareStatement(sql);
ResultSet resultSet = query.executeQuery();
while (resultSet.next()) {
String id = resultSet.getString(1);
String value = resultSet.getString(2);
if (id != null && value != null) {
map.setProperty(id, value);
}
}
map.store(outputStream, null);
}
private void processXmlEntity(Connection c, Properties map, FileOutputStream outputStream) throws SQLException, IOException {
PreparedStatement query = c.prepareStatement(SELECT_FOR_XML_ENTITY);
ResultSet resultSet = query.executeQuery();
while (resultSet.next()) {
String id = resultSet.getString(1);
Blob value = resultSet.getBlob(2);
byte[] bytes = value.getBytes(1L, (int) value.length());
map.setProperty(id, new String(bytes));
}
map.store(outputStream, null);
}
public void deletePropertiesCache() {
CommonUtils.deleteFile(new File(PropertiesConstants.ENTITY_PROP_PATH));
CommonUtils.deleteFile(new File(PropertiesConstants.XML_ENTITY_PROP_PATH));
CommonUtils.deleteFile(new File(PropertiesConstants.CLASS_NAME_PROP_PATH));
}
}

34
designer-base/src/main/java/com/fr/file/FILEChooserPane.java

@ -202,10 +202,11 @@ public class FILEChooserPane extends BasicPane {
return INSTANCE;
}
public static FILEChooserPane getInstanceWithDesignatePath(String path, FILEFilter filter) {
public static FILEChooserPane getInstanceWithDesignatePath(String path, FILEFilter filter, String topPath) {
INSTANCE.showLoc = false;
INSTANCE.showEnv = false;
INSTANCE.showWebReport = false;
INSTANCE.setTopPath(topPath);
INSTANCE.setDesignateModel(path);
INSTANCE.removeAllFilter();
INSTANCE.addChooseFILEFilter(filter, 0);
@ -633,6 +634,9 @@ public class FILEChooserPane extends BasicPane {
this.filterList.clear();
}
public void removeTopPath() {
this.setTopPath(StringUtils.EMPTY);
}
/**
* 设置filter,刷新右侧subFileList中的items
@ -1045,9 +1049,14 @@ public class FILEChooserPane extends BasicPane {
if (placesList == null) {
return;
}
setPlaceListModel(new DesignateRemotePlaceListModel(path));
}
private void setTopPath(String path) {
this.locationBtnPane.setTopPath(path);
}
private void setMultiPlaceListModel() {
if (placesList == null) {
@ -1385,6 +1394,8 @@ public class FILEChooserPane extends BasicPane {
private List<UIButton> buttonList = new ArrayList<>();
private int pathIndex = 0;
private int maxPathIndex = 0;
// 对顶层目录进行的限制
private String topPath;
public LocationButtonPane() {
this.setLayout(FRGUIPaneFactory.createBoxFlowLayout());
@ -1430,6 +1441,10 @@ public class FILEChooserPane extends BasicPane {
});
}
public void setTopPath(String path) {
this.topPath = path;
}
public void highLightButton(FILE dir) {
for (int i = 0; i < this.buttonList.size(); i++) {
this.buttonList.get(i).setForeground(null);
@ -1471,6 +1486,7 @@ public class FILEChooserPane extends BasicPane {
}
Matcher matcher = SEPARATOR_PATTERN.matcher(path);
int node_start = 0;
boolean needTopPath = !StringUtils.isEmpty(topPath);
while (matcher.find()) {
int start = matcher.start();
String btn_text = path.substring(node_start, start);
@ -1478,11 +1494,14 @@ public class FILEChooserPane extends BasicPane {
if (StringUtils.isBlank(btn_text) && isWebAppNamePath) {
btn_text = webAppName;
}
node_start = matcher.end();
if (needTopPath && topPath.equals(btn_text)) {
needTopPath = false;
}
this.buttonList.add(createBlankButton((new SetDirectoryAction(btn_text + '/',
// alex:dir.prefix不和btn_path一起参与pathJoin,因为btn_path是否以/打头在unix,linux
// OS中意义很不一样
FILEFactory.createFolder(dir.prefix() + StableUtils.pathJoin(btn_path, "/"))))));
node_start = matcher.end();
FILEFactory.createFolder(dir.prefix() + StableUtils.pathJoin(btn_path, "/")), !needTopPath))));
}
maxPathIndex = calculateMaxPathIndex();
@ -1583,6 +1602,7 @@ public class FILEChooserPane extends BasicPane {
private class SetDirectoryAction extends UpdateAction {
private FILE dir;
private boolean response = true;
public SetDirectoryAction(String name) {
this.setName(name);
@ -1594,9 +1614,15 @@ public class FILEChooserPane extends BasicPane {
this.dir = file;
}
public SetDirectoryAction(String name, FILE file, boolean response) {
this.setName(name);
this.dir = file;
this.response = response;
}
@Override
public void actionPerformed(ActionEvent evt) {
if (dir != null) {
if (dir != null && response) {
setSelectedDirectory(dir);
}
}

2
designer-base/src/main/java/com/fr/start/BaseDesigner.java

@ -32,6 +32,7 @@ import com.fr.process.engine.core.CarryMessageEvent;
import com.fr.process.engine.core.FineProcessContext;
import com.fr.stable.OperatingSystem;
import com.fr.start.event.LazyStartupEvent;
import com.fr.workspace.base.WorkspaceStatus;
import java.awt.Window;
import java.io.File;
@ -86,6 +87,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock {
eventPipe.fire(new CarryMessageEvent(ReportState.STOP.getValue()));
}
EventDispatcher.fire(WorkspaceStatus.Prepared);
EventDispatcher.asyncFire(LazyStartupEvent.INSTANCE);
collectUserInformation();
}
});

14
designer-base/src/main/java/com/fr/start/event/LazyStartupEvent.java

@ -0,0 +1,14 @@
package com.fr.start.event;
import com.fr.event.Event;
import com.fr.event.Null;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/3/7
*/
public enum LazyStartupEvent implements Event<Null> {
INSTANCE
}

8
designer-base/src/main/resources/com/fr/design/gui/syntax/ui/rsyntaxtextarea/modes/FormulaTokenMaker.flex

@ -584,7 +584,13 @@ FunctionNames = "ABS"|
"QUERY"|
"query"|
"WEBIMAGE"|
"webimage"
"webimage"|
"ACCSUM"|
"accsum"|
"COUNTIFS"|
"countifs"|
"SUMIFS"|
"sumifs"
%state MLC

139
designer-base/src/test/java/com/fr/design/record/analyzer/BytebuddyRedefineTest.java

@ -0,0 +1,139 @@
package com.fr.design.record.analyzer;
import com.fr.third.net.bytebuddy.ByteBuddy;
import com.fr.third.net.bytebuddy.agent.ByteBuddyAgent;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import com.fr.third.net.bytebuddy.matcher.ElementMatchers;
import com.fr.third.org.apache.commons.lang3.time.StopWatch;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.TimeUnit;
/**
* 测试一下通过 redefine 去处理代码时
* 相应的 advice 应该怎么写
*/
public class BytebuddyRedefineTest {
/**
* 测试一下是否可以直接抛出异常
*/
@Test
public void testThrowException() {
try {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestThrowExceptionAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
TestClass testClass = new TestClass();
testClass.testPrint();
} catch (Throwable throwable) {
Assert.assertNotNull("expected throw exception", throwable);
}
}
/**
* 测试是否可以直接传值
*/
@Test
public void testTransferValue() {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestTransferValueAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
TestClass testClass = new TestClass();
String print = testClass.testPrint();
Assert.assertEquals(10, TestTransferValueAdvice.intField);
Assert.assertEquals("[test]stringField", TestTransferValueAdvice.stringField);
Assert.assertEquals("[test]objectField", TestTransferValueAdvice.objectField);
}
/**
* 测试是否可以改变返回值
*/
@Test
public void testModifyReturn() {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestModifyReturnAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
TestClass testClass = new TestClass();
String print = testClass.testPrint();
Assert.assertEquals("[test]Modify Return Value", print);
}
@Test
public void testCallable() throws Exception {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestCallableAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
TestClass testClass = new TestClass();
String print = testClass.testPrint();
Assert.assertEquals("[test]Callable", print);
}
@Test
public void testCallablePerformance() throws Exception {
// 千
int loop = 1000;
StopWatch stopWatch = new StopWatch();
stopWatch.start();
TestClass rawClass = new TestClass();
for (int i = 0; i < loop; i++) {
rawClass.testPrint();
}
System.out.printf("raw class run %s cost %s ms \n", loop, stopWatch.getTime(TimeUnit.MILLISECONDS));
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(TestClass.class)
.visit(Advice.to(TestCallableAdvice.class).on(ElementMatchers.named("testPrint")))
.make()
.load(TestClass.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
stopWatch.reset();
stopWatch.start();
TestClass retransformClass = new TestClass();
for (int i = 0; i < loop; i++) {
retransformClass.testPrint();
}
System.out.printf("retransformClass class run %s cost %s ms \n", loop, stopWatch.getTime(TimeUnit.MILLISECONDS));
Assert.assertEquals("[test]Callable", retransformClass.testPrint());
}
}

50
designer-base/src/test/java/com/fr/design/record/analyzer/TestCallableAdvice.java

@ -0,0 +1,50 @@
package com.fr.design.record.analyzer;
import com.fr.record.analyzer.advice.AdviceCallable;
import com.fr.record.analyzer.advice.AdviceContext;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import com.fr.tolerance.FaultTolerance;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
/**
* created by Harrison on 2022/03/09
**/
public class TestCallableAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static boolean onMethodEnter(@Advice.Local("context")AdviceContext adviceContext) {
adviceContext = AdviceContext
.builder()
.onAdviceCall()
.build();
// 如果是切面调用,则忽视当前方法
return adviceContext.isOnAdviceCall();
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result,
@Advice.Local("context") AdviceContext adviceContext) throws Exception {
// 如果是切面调用,则忽视不继续 exit
if (adviceContext != null && adviceContext.isOnAdviceCall()) {
return;
}
FaultTolerance faultTolerance = method.getAnnotation(FaultTolerance.class);
Callable<Object> callable = new AdviceCallable<Object>() {
@Override
public Object call() throws Exception {
return method.invoke(self, args);
}
};
result = TestCallableHelper.test(callable);
}
}

15
designer-base/src/test/java/com/fr/design/record/analyzer/TestCallableHelper.java

@ -0,0 +1,15 @@
package com.fr.design.record.analyzer;
import java.util.concurrent.Callable;
/**
* created by Harrison on 2022/03/09
**/
public class TestCallableHelper {
public static String test(Callable<Object> callable) throws Exception {
callable.call();
return "[test]Callable";
}
}

11
designer-base/src/test/java/com/fr/design/record/analyzer/TestClass.java

@ -0,0 +1,11 @@
package com.fr.design.record.analyzer;
/**
* created by Harrison on 2022/03/04
**/
public class TestClass {
public String testPrint() {
return "";
}
}

29
designer-base/src/test/java/com/fr/design/record/analyzer/TestModifyReturnAdvice.java

@ -0,0 +1,29 @@
package com.fr.design.record.analyzer;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
/**
* created by Harrison on 2022/03/07
**/
public class TestModifyReturnAdvice {
@Advice.OnMethodEnter(skipOn = Advice.OnDefaultValue.class)
public static int onMethodEnter() throws Exception {
return 0;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.This(optional = true, typing = Assigner.Typing.DYNAMIC) Object self,
@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args,
@Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object result) throws Exception {
result = "[test]Modify Return Value";
}
}

19
designer-base/src/test/java/com/fr/design/record/analyzer/TestThrowExceptionAdvice.java

@ -0,0 +1,19 @@
package com.fr.design.record.analyzer;
import com.fr.third.net.bytebuddy.asm.Advice;
import com.fr.third.net.bytebuddy.implementation.bytecode.assign.Assigner;
import java.lang.reflect.Method;
/**
* created by Harrison on 2022/03/07
**/
public class TestThrowExceptionAdvice {
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.Origin Method method,
@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] arguments,
@Advice.Thrown(typing = Assigner.Typing.DYNAMIC) Exception e) throws Exception {
throw new RuntimeException("[test] throw exception in advice");
}
}

37
designer-base/src/test/java/com/fr/design/record/analyzer/TestTransferValueAdvice.java

@ -0,0 +1,37 @@
package com.fr.design.record.analyzer;
import com.fr.third.net.bytebuddy.asm.Advice;
/**
* created by Harrison on 2022/03/07
**/
public class TestTransferValueAdvice {
public static int intField;
public static String stringField;
public static Object objectField;
@Advice.OnMethodEnter
public static void onMethodEnter(@Advice.Local("int") int intField,
@Advice.Local("string") String stringField,
@Advice.Local("Object") Object objectField) {
intField = 10;
stringField = "[test]stringField";
objectField = "[test]objectField";
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void onMethodExit(@Advice.Local("int") int intField,
@Advice.Local("string") String stringField,
@Advice.Local("Object") Object objectField) throws Exception {
TestTransferValueAdvice.intField = intField;
TestTransferValueAdvice.stringField = stringField;
TestTransferValueAdvice.objectField = objectField;
}
}

2
designer-chart/src/main/java/com/fr/design/module/ChartHyperlinkGroup.java

@ -59,7 +59,7 @@ public class ChartHyperlinkGroup extends BaseHyperlinkGroup {
return false;
}
if (template.isJWorkBook() || DesignModeContext.isDuchampMode()) {
if (template.isJWorkBook()) {
// 如果是普通报表单元格,那么没有 FormHyperlink 选项
FormHyperlinkProvider formHyperlink = StableFactory.getMarkedInstanceObjectFromClass(FormHyperlinkProvider.XML_TAG, FormHyperlinkProvider.class);
//返回true表示可用,返回false表示不可用

2
designer-chart/src/main/java/com/fr/van/chart/designer/component/background/VanChartBackgroundPaneWithThemeStyle.java

@ -25,7 +25,7 @@ public class VanChartBackgroundPaneWithThemeStyle extends VanChartBackgroundPane
}
});
paneList.add(new NullBackgroundQuickPane());
paneList.add(new ColorBackgroundQuickPane());
paneList.add(new ColorBackgroundQuickPane(true));
paneList.add(new ImageBackgroundQuickPane(false));
paneList.add(new VanChartGradientPane());
}

15
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopDialog.java

@ -1,15 +1,13 @@
package com.fr.design.mainframe.share.ui.online.mini;
import com.fr.base.ScreenResolution;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.share.mini.MiniShopDisposingChecker;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.Constants;
import com.fr.stable.unit.FU;
import com.fr.stable.unit.UNIT;
import javax.swing.JFrame;
import java.awt.Container;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
@ -36,10 +34,11 @@ public class MiniComponentShopDialog {
final JFrame frame = new JFrame();
final MiniComponentShopPane shopPane = new MiniComponentShopPane();
final UNIT width = FU.getInstance(900 * Constants.FU_PER_OLD_PIX);
final UNIT height = FU.getInstance(600 * Constants.FU_PER_OLD_PIX);
int resolution = ScreenResolution.getScreenResolution();
frame.setSize(width.toPixI(resolution), height.toPixI(resolution));
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle rect =ge.getMaximumWindowBounds();
int width = (int) (rect.width * 0.8);
int height = (int) (rect.height * 0.9);
frame.setSize(width, height);
frame.setTitle(Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Window_Title"));
frame.add(shopPane);
frame.setResizable(false);

39
designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java

@ -254,9 +254,9 @@ public class NativeProductBridge {
MiniComponentShopDialog.getInstance().getContentPane(),
Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Incompatible_Component_Tip"),
"",
FineJOptionPane.YES_NO_OPTION
FineJOptionPane.OK_CANCEL_OPTION
);
allowedDownload = result == JOptionPane.YES_OPTION;
allowedDownload = result == JOptionPane.OK_OPTION;
}
if (allowedDownload) {
fireStartEvent(null);
@ -353,33 +353,14 @@ public class NativeProductBridge {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
boolean allowedDownload;
OnlineShareWidget[] childrenWidgets = OnlineShopUtils.getPackageWidgets(widget, false);
boolean isCompatibleWithCurrentEnv = true;
for (OnlineShareWidget children: childrenWidgets) {
if (!children.isCompatibleWithCurrentEnv()) {
isCompatibleWithCurrentEnv = false;
break;
}
}
int result;
if (!isCompatibleWithCurrentEnv) {
result = FineJOptionPane.showConfirmDialog(
MiniComponentShopDialog.getInstance().getContentPane(),
Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Incompatible_Components_Package_Tip", childrenCount),
"",
FineJOptionPane.YES_NO_OPTION
);
} else {
result = FineJOptionPane.showConfirmDialog(
MiniComponentShopDialog.getInstance().getContentPane(),
Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Components_Package_Tip", childrenCount),
"",
FineJOptionPane.YES_NO_OPTION
);
}
allowedDownload = result == JOptionPane.YES_OPTION;
if (allowedDownload) {
OnlineShareWidget[] childrenWidgets = OnlineShopUtils.getPackageWidgets(widget, true);
int result = FineJOptionPane.showConfirmDialog(
MiniComponentShopDialog.getInstance().getContentPane(),
Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Components_Package_Tip", childrenWidgets.length),
"",
FineJOptionPane.OK_CANCEL_OPTION
);
if (result == JOptionPane.OK_OPTION) {
fireStartEvent(null);
action.install();
} else {

4
designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java

@ -76,7 +76,7 @@ public class TreeEditorDefinePane extends CustomWritableRepeatEditorPane<TreeEdi
@Override
protected void populateSubCustomWritableRepeatEditorBean(TreeEditor e) {
accessibleTreeModelEditor.setValue(e.getNodeOrDict());
accessibleTreeModelEditor.setValue(e.getBuildModelConfig());
formWidgetValuePane.populate(e);
treeRootPane.populate(e.getTreeAttr());
mutiSelect.setSelected(e.isMultipleSelection());
@ -95,7 +95,7 @@ public class TreeEditorDefinePane extends CustomWritableRepeatEditorPane<TreeEdi
editor.setAjax(loadAsync.isSelected());
editor.setSelectLeafOnly(returnLeaf.isSelected());
editor.setReturnFullPath(returnPath.isSelected());
editor.setNodeOrDict(accessibleTreeModelEditor.getValue());
editor.setBuildModelConfig(accessibleTreeModelEditor.getValue());
return editor;
}

7
designer-realize/src/main/java/com/fr/design/mainframe/HyperlinkGroupPaneActionImpl.java

@ -86,7 +86,12 @@ public class HyperlinkGroupPaneActionImpl implements HyperlinkGroupPaneActionPro
frFont = frFont.applyForeground(AdjustWorkBookDefaultStyleUtils.adjustCellElementFontForeground(Color.black));
frFont = frFont.applyUnderline(Constants.LINE_NONE);
}
editCellElement.setStyle(elementStyle.deriveFRFont(frFont));
// 首次添加超链接,将文字样式默认改为蓝色下划线
if (updateNameHyperlinks.size() == 1 && hyperlinkGroupPane.getSelectedIndex() == 0) {
editCellElement.setStyle(elementStyle.deriveFRFont(frFont));
}
try {
editCellElement.setNameHyperlinkGroup((NameJavaScriptGroup) updateNameHyperlinks.clone());
} catch (CloneNotSupportedException e) {

4
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java

@ -553,9 +553,9 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
textOverflowTypeComboBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_NoneSymbol"));
}
} else {
showPartComboBox.setSelectedIndex(0);
showPartComboBox.setSelectedIndex(cellGUIAttr.isShowCharNum() ? 0 : 1);
showCharNums.setValue(cellGUIAttr.getShowCharNums());
textOverflowTypeComboBox.setSelectedIndex(0);
textOverflowTypeComboBox.setSelectedIndex(cellGUIAttr.isTextOverflowEllipsis() ? 0 : 1);
textOverflowCheckBox.setSelected(false);
}
CellPageAttr cellPageAttr = cellElement.getCellPageAttr(); // 分页

3
designer-realize/src/main/java/com/fr/design/webattr/WriteWebSettingPane.java

@ -4,6 +4,7 @@ import com.fr.base.BaseUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.gui.core.WidgetOption;
import com.fr.design.gui.ibutton.UIColorButton;
import com.fr.design.gui.ibutton.UINoThemeColorButton;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
@ -44,7 +45,7 @@ public class WriteWebSettingPane extends WebSettingPane<WebWrite> {
protected JPanel createOtherSetPane() {
colorBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set_Background_Of_Current_Row") + ":");
colorBox.setSelected(true);
colorButton = new UIColorButton(BaseUtils.readIcon("/com/fr/design/images/gui/color/background.png"));
colorButton = new UINoThemeColorButton(BaseUtils.readIcon("/com/fr/design/images/gui/color/background.png"));
colorBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
colorButton.setEnabled(colorBox.isSelected());

14
designer-realize/src/main/java/com/fr/design/widget/ui/TreeComboBoxEditorDefinePane.java

@ -48,7 +48,7 @@ public class TreeComboBoxEditorDefinePane extends CustomWritableRepeatEditorPane
}
@Override
protected String title4PopupWindow() {
return "treecombobox";
@ -56,20 +56,20 @@ public class TreeComboBoxEditorDefinePane extends CustomWritableRepeatEditorPane
@Override
protected void populateSubCustomWritableRepeatEditorBean(TreeEditor e) {
treeSettingPane.setValue(e.getNodeOrDict());
treeSettingPane.setValue(e.getBuildModelConfig());
treeRootPane.populate(e.getTreeAttr());
}
@Override
protected TreeComboBoxEditor updateSubCustomWritableRepeatEditorBean() {
TreeComboBoxEditor editor = new TreeComboBoxEditor();
editor.setNodeOrDict(treeSettingPane.getValue());
editor.setBuildModelConfig(treeSettingPane.getValue());
editor.setTreeAttr(treeRootPane.update());
return editor;
}
@Override
public DataCreatorUI dataUI() {
return null;
}
@Override
public DataCreatorUI dataUI() {
return null;
}
}

20
designer-realize/src/main/java/com/fr/design/widget/ui/TreeEditorDefinePane.java

@ -25,12 +25,12 @@ public class TreeEditorDefinePane extends FieldEditorDefinePane<TreeEditor> {
private UICheckBox removeRepeatCheckBox;
public TreeEditorDefinePane(){
this.initComponents();
this.initComponents();
}
@Override
protected void populateSubFieldEditorBean(TreeEditor e) {
this.accessibleTreeModelEditor.setValue(e.getNodeOrDict());
this.accessibleTreeModelEditor.setValue(e.getBuildModelConfig());
treeRootPane.populate(e.getTreeAttr());
if (this.removeRepeatCheckBox != null) {
this.removeRepeatCheckBox.setSelected(e.isRemoveRepeat());
@ -40,7 +40,7 @@ public class TreeEditorDefinePane extends FieldEditorDefinePane<TreeEditor> {
@Override
protected TreeEditor updateSubFieldEditorBean() {
TreeEditor editor = new TreeEditor();
editor.setNodeOrDict(accessibleTreeModelEditor.getValue());
editor.setBuildModelConfig(accessibleTreeModelEditor.getValue());
editor.setTreeAttr(treeRootPane.update());
if (this.removeRepeatCheckBox != null) {
editor.setRemoveRepeat(this.removeRepeatCheckBox.isSelected());
@ -50,8 +50,8 @@ public class TreeEditorDefinePane extends FieldEditorDefinePane<TreeEditor> {
@Override
protected JPanel setFirstContentPane() {
return this.setSecondContentPane();
}
return this.setSecondContentPane();
}
protected JPanel setSecondContentPane() {
accessibleTreeModelEditor = new AccessibleTreeModelEditor();
@ -80,14 +80,14 @@ public class TreeEditorDefinePane extends FieldEditorDefinePane<TreeEditor> {
content.add(treeRootPane, BorderLayout.NORTH);
return content;
}
@Override
protected String title4PopupWindow() {
return "tree";
}
@Override
public DataCreatorUI dataUI() {
return null;
}
@Override
public DataCreatorUI dataUI() {
return null;
}
}

38
designer-realize/src/main/java/com/fr/start/MainDesigner.java

@ -16,6 +16,7 @@ import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.fun.MenuHandler;
import com.fr.design.fun.OemProcessor;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIPreviewButton;
import com.fr.design.gui.ibutton.UISaveForbiddenButton;
@ -42,6 +43,7 @@ import com.fr.design.module.DesignModuleFactory;
import com.fr.design.monitor.DesignerLifecycleMonitorContext;
import com.fr.design.notification.ui.NotificationCenterPane;
import com.fr.design.share.SharableManager;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.concurrent.ThreadFactoryBuilder;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.env.utils.DesignerInteractionHistory;
@ -59,6 +61,7 @@ import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.lifecycle.FineLifecycleFatalError;
import com.fr.stable.xml.XMLTools;
import com.fr.start.common.SplashCommon;
import com.fr.start.module.StartupArgs;
import com.fr.start.server.ServerTray;
import com.fr.third.org.apache.commons.lang3.time.StopWatch;
@ -106,7 +109,8 @@ public class MainDesigner extends BaseDesigner {
* @param args 参数
*/
public static void main(String[] args) {
showSplash();
DeepLinkManager.getInstance().start(args);
StopWatch watch = new StopWatch();
watch.start();
@ -136,7 +140,18 @@ public class MainDesigner extends BaseDesigner {
FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", watch.getTime());
watch.stop();
}
private static void showSplash() {
// 快快显示启动画面
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
SplashContext.getInstance().registerSplash(createSplash());
SplashContext.getInstance().show();
}
});
}
/**
* 创建新建文件的快捷方式数组
*
@ -528,5 +543,22 @@ public class MainDesigner extends BaseDesigner {
DesignerInteractionHistory historyCollector = DesignerInteractionHistory.getInstance();
historyCollector.saveXMLFile();
}
private static SplashStrategy createSplash() {
OemProcessor oemProcessor = OemHandler.findOem();
if (oemProcessor != null) {
SplashStrategy splashStrategy = null;
try {
splashStrategy = oemProcessor.createSplashStrategy();
} catch (Throwable e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
if (splashStrategy != null) {
return splashStrategy;
}
}
return new SplashCommon();
}
}

2
designer-realize/src/main/java/com/fr/start/SplashContext.java

@ -36,7 +36,7 @@ public class SplashContext {
private SplashStrategy splashStrategy;
private String moduleId = "";
private String moduleId = Toolkit.i18nText("Fine-Design_Basic_Initializing");
private int loadingIndex = 0;
private String[] loading = new String[]{"..", "....", "......"};

24
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -3,6 +3,7 @@ package com.fr.start.module;
import com.fr.base.BaseFormula;
import com.fr.base.Formula;
import com.fr.base.MultiFieldParameter;
import com.fr.base.OptimizeUtil;
import com.fr.base.passport.FinePassportListenerAdapter;
import com.fr.base.passport.FinePassportManager;
import com.fr.base.process.ProcessOperator;
@ -80,7 +81,10 @@ import com.fr.design.share.ui.generate.ShareGeneratePane;
import com.fr.design.update.actions.RecoverForDesigner;
import com.fr.design.update.push.DesignerPushUpdateManager;
import com.fr.design.widget.ui.btn.FormSubmitButtonDetailPane;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.general.GeneralContext;
import com.fr.general.xml.GeneralXMLTools;
import com.fr.js.EmailJavaScript;
@ -159,6 +163,8 @@ public class DesignerActivator extends Activator implements Prepare {
@Override
public void start() {
startLoginAuthServer();
migrateBBSInfoFromFineDB();
FormThemeConfigMigrator.getInstance().upgrade();
ReportThemeConfigMigrator.getInstance().upgrade();
@ -488,7 +494,23 @@ public class DesignerActivator extends Activator implements Prepare {
@Override
public void prepare() {
LoginAuthServer.getInstance().start();
OptimizeUtil.close(() -> {
LoginAuthServer.getInstance().compatibleStart();
});
ContentReplacerCenter.getInstance().register();
}
private void startLoginAuthServer() {
OptimizeUtil.open(() -> {
// 设计器启动后启动
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
LoginAuthServer.getInstance().start();
}
});
});
}
}

102
designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java

@ -1,36 +1,39 @@
package com.fr.start.module;
import com.fr.base.OptimizeUtil;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.config.dao.DaoSelectorFactory;
import com.fr.decision.webservice.v10.encryption.EncryptionConstants;
import com.fr.design.DesignerEnvManager;
import com.fr.design.RestartHelper;
import com.fr.design.dialog.TipDialog;
import com.fr.design.fun.OemProcessor;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.DesignerWorkspaceType;
import com.fr.design.fun.impl.GlobalListenerProviderManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector;
import com.fr.design.mainframe.messagecollect.StartupMessageCollector;
import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.DesignerPort;
import com.fr.env.utils.WorkspaceUtils;
import com.fr.event.Event;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.exit.DesignerExiter;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.module.Activator;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.record.analyzer.Metrics;
import com.fr.stable.ArrayUtils;
import com.fr.stable.BuildContext;
import com.fr.stable.ProductConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.start.DesignerProcessType;
import com.fr.start.OemHandler;
import com.fr.start.ServerStarter;
import com.fr.start.SplashContext;
import com.fr.start.SplashStrategy;
import com.fr.start.common.SplashCommon;
import com.fr.start.event.LazyStartupEvent;
import com.fr.start.server.FineEmbedServer;
import com.fr.value.NotNullLazyValue;
import org.jetbrains.annotations.NotNull;
@ -55,10 +58,9 @@ public class DesignerStartup extends Activator {
@Override
public void beforeAllStart() {
BuildContext.setBuildFilePath("/com/fr/stable/build.properties");
// 检查是否是-Ddebug = true 启动 并切换对应的端口以及环境配置文件
checkDebugStart();
// 都是在启动过程中读取,这边提前初始化xml配置
DesignerEnvManager.getEnvManager();
registerDaoSelector();
// 初始化look and feel
DesignUtils.initLookAndFeel();
if (DesignUtils.isPortOccupied()) {
@ -100,14 +102,6 @@ public class DesignerStartup extends Activator {
DesignerExiter.getInstance().execute();
return;
}
// 快快显示启动画面
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
SplashContext.getInstance().registerSplash(createSplash());
SplashContext.getInstance().show();
}
});
}
@Override
@ -125,13 +119,21 @@ public class DesignerStartup extends Activator {
|| FineEmbedServer.isRunning()) {
return;
}
if (DaoSelectorFactory.getDaoSelector().useCacheDao()) {
listenEvent(LazyStartupEvent.INSTANCE, new Listener<Null>(Integer.MIN_VALUE) {
@Override
public void on(Event event, Null param) {
startEmbeddedServer();
}
});
} else {
startEmbeddedServer();
}
}
private void startEmbeddedServer() {
ExecutorService service = newSingleThreadExecutor(new NamedThreadFactory("FineEmbedServerStart"));
service.submit(new Runnable() {
@Override
public void run() {
FineEmbedServer.start();
}
});
service.submit(FineEmbedServer::start);
service.shutdown();
}
@ -142,23 +144,6 @@ public class DesignerStartup extends Activator {
StartupMessageCollector.getInstance().recordStartupLog();
}
private SplashStrategy createSplash() {
OemProcessor oemProcessor = OemHandler.findOem();
if (oemProcessor != null) {
SplashStrategy splashStrategy = null;
try {
splashStrategy = oemProcessor.createSplashStrategy();
} catch (Throwable e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
if (splashStrategy != null) {
return splashStrategy;
}
}
return new SplashCommon();
}
private void browserDemoIfNeeded() {
if (startupArgsValue.getValue().isDemo()) {
@ -166,28 +151,21 @@ public class DesignerStartup extends Activator {
}
}
/**
* 在VM options里加入-Ddebug=true激活
*/
private void checkDebugStart() {
if (ComparatorUtils.equals("true", System.getProperty("debug"))) {
setDebugEnv();
private void registerDaoSelector() {
// 注入设计器db cache 是否可用
DesignerWorkspaceInfo info = WorkspaceUtils.getWorkspaceInfo();
if (info.getType() == DesignerWorkspaceType.Remote) {
DaoSelectorFactory.registerDaoSelector(() -> false);
} else {
String dbConfigPath = StableUtils.pathJoin(WorkspaceUtils.getWorkspaceInfo().getPath(), ProjectConstants.CONFIG_DIRECTORY,
EncryptionConstants.PROPERTY_NAME);
//
DaoSelectorFactory.registerDaoSelector(() -> DesignerEnvManager.getEnvManager().isPropertiesUsable()
&& OptimizeUtil.isOpen()
&& !new File(dbConfigPath).exists());
}
}
/**
* 端口改一下环境配置文件改一下便于启动两个设计器进行对比调试
*/
private void setDebugEnv() {
DesignUtils.setPort(DesignerPort.getInstance().getDebugMessagePort());
DesignerEnvManager.setEnvFile(new File(StableUtils.pathJoin(
ProductConstants.getEnvHome(),
ProductConstants.APP_NAME + "Env_debug.xml"
)));
}
@Override
public void stop() {
// void

9
designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java

@ -9,6 +9,7 @@ import com.fr.design.env.DesignerWorkspaceGenerator;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.LocalDesignerWorkspaceInfo;
import com.fr.design.versioncheck.VersionCheckUtils;
import com.fr.env.utils.WorkspaceUtils;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
@ -28,7 +29,6 @@ import org.jetbrains.annotations.NotNull;
*/
public class DesignerWorkspaceProvider extends Activator {
private static final String SPECIFY_WORKSPACE = "fr.designer.workspace";
private NotNullLazyValue<StartupArgs> startupArgs = new NotNullLazyValue<StartupArgs>() {
@NotNull
@ -46,15 +46,10 @@ public class DesignerWorkspaceProvider extends Activator {
if (startupArgs.getValue().isDemo()) {
DesignerEnvManager.getEnvManager().setCurrentEnv2Default();
} else {
String workspacePath;
DesignerWorkspaceInfo workspaceInfo = null;
try {
String current = DesignerEnvManager.getEnvManager().getCurEnvName();
if (StringUtils.isNotEmpty(workspacePath = System.getProperty(SPECIFY_WORKSPACE))) {
workspaceInfo = LocalDesignerWorkspaceInfo.create(StringUtils.EMPTY, workspacePath);
} else {
workspaceInfo = DesignerEnvManager.getEnvManager().getWorkspaceInfo(current);
}
workspaceInfo = WorkspaceUtils.getWorkspaceInfo();
Workspace workspace = DesignerWorkspaceGenerator.generate(workspaceInfo);
boolean checkValid = workspace != null && workspaceInfo.checkValid();
if (!checkValid) {

8
designer-realize/src/main/java/com/fr/start/module/PreStartActivator.java

@ -2,14 +2,11 @@ package com.fr.start.module;
import com.fr.design.DesignerEnvManager;
import com.fr.design.RestartHelper;
import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.DesignUtils;
import com.fr.event.EventDispatcher;
import com.fr.file.TmpFileUtils;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.module.Activator;
import com.fr.module.ModuleEvent;
/**
* Created by juhaoyu on 2018/1/8.
@ -21,8 +18,9 @@ public class PreStartActivator extends Activator {
//清空临时文件
TmpFileUtils.cleanUpInnerTmpFiles();
RestartHelper.deleteRecordFilesWhenStart();
//初始化
EventDispatcher.fire(ModuleEvent.MajorModuleStarting, Toolkit.i18nText("Fine-Design_Basic_Initializing"));
//初始化起始画面放到 SplashContext 里面
//EventDispatcher.fire(ModuleEvent.MajorModuleStarting, Toolkit.i18nText("Fine-Design_Basic_Initializing"));
// 完成初始化
//noinspection ResultOfMethodCallIgnored
CloudCenter.getInstance();

30
designer-realize/src/main/java/com/fr/start/module/optimized/BaseDBActivator4Designer.java

@ -0,0 +1,30 @@
package com.fr.start.module.optimized;
import com.fr.config.activator.BaseDBActivator;
import com.fr.config.dao.DaoSelectorFactory;
import com.fr.event.Event;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.start.event.LazyStartupEvent;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/3/7
*/
public class BaseDBActivator4Designer extends BaseDBActivator {
@Override
public void start() {
if (DaoSelectorFactory.getDaoSelector().useCacheDao()) {
listenEvent(LazyStartupEvent.INSTANCE, new Listener<Null>(Integer.MAX_VALUE) {
@Override
public void on(Event event, Null param) {
BaseDBActivator4Designer.super.start();
}
});
} else {
super.start();
}
}
}

27
designer-realize/src/main/java/com/fr/start/module/optimized/ConfigurationActivator4Designer.java

@ -0,0 +1,27 @@
package com.fr.start.module.optimized;
import com.fr.config.activator.ConfigurationActivator;
import com.fr.config.dao.DaoContext;
import com.fr.config.dao.DaoSelectorFactory;
import com.fr.config.dao.impl.PropertiesClassHelperDao;
import com.fr.config.dao.impl.PropertiesEntityDao;
import com.fr.config.dao.impl.PropertiesXmlEntityDao;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/3/7
*/
public class ConfigurationActivator4Designer extends ConfigurationActivator {
@Override
protected void initLocalDao() {
if (DaoSelectorFactory.getDaoSelector().useCacheDao()) {
DaoContext.setClassHelperDao(new PropertiesClassHelperDao());
DaoContext.setEntityDao(new PropertiesEntityDao());
DaoContext.setXmlEntityDao(new PropertiesXmlEntityDao());
} else {
super.initLocalDao();
}
}
}

32
designer-realize/src/main/java/com/fr/start/module/optimized/ReportBaseActivator4Designer.java

@ -0,0 +1,32 @@
package com.fr.start.module.optimized;
import com.fr.config.dao.DaoSelectorFactory;
import com.fr.event.Event;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.report.module.ReportBaseActivator;
import com.fr.start.event.LazyStartupEvent;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/3/16
*/
public class ReportBaseActivator4Designer extends ReportBaseActivator {
@Override
protected void vcsInit() {
if (DaoSelectorFactory.getDaoSelector().useCacheDao()) {
listenEvent(LazyStartupEvent.INSTANCE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
ReportBaseActivator4Designer.super.vcsInit();
}
});
} else {
super.vcsInit();
}
}
}

42
designer-realize/src/main/java/com/fr/start/module/optimized/TenantDBAdapter4Designer.java

@ -0,0 +1,42 @@
package com.fr.start.module.optimized;
import com.fr.config.dao.DaoSelectorFactory;
import com.fr.config.dao.swicter.DaoSwitcher;
import com.fr.design.DesignerEnvManager;
import com.fr.event.Event;
import com.fr.event.Listener;
import com.fr.event.Null;
import com.fr.exit.ConfigToPropMigrator;
import com.fr.stable.db.tenant.TenantDBAdapter;
import com.fr.start.event.LazyStartupEvent;
/**
* @author hades
* @version 11.0
* Created by hades on 2022/3/7
*/
public class TenantDBAdapter4Designer extends TenantDBAdapter {
@Override
public void start() {
if (DaoSelectorFactory.getDaoSelector().useCacheDao()) {
listenEvent(LazyStartupEvent.INSTANCE, new Listener<Null>() {
@Override
public void on(Event event, Null param) {
TenantDBAdapter4Designer.super.start();
afterStart();
}
});
} else {
super.start();
}
}
private void afterStart() {
DesignerEnvManager.getEnvManager().setPropertiesUsable(false);
DaoSwitcher.executeSwitch();
ConfigToPropMigrator.getInstance().deletePropertiesCache();
DesignerEnvManager.getEnvManager().saveXMLFile();
}
}
Loading…
Cancel
Save