diff --git a/designer-base/src/main/java/com/fr/design/ExtraDesignClassManager.java b/designer-base/src/main/java/com/fr/design/ExtraDesignClassManager.java index beb62c06e..77e0eb115 100644 --- a/designer-base/src/main/java/com/fr/design/ExtraDesignClassManager.java +++ b/designer-base/src/main/java/com/fr/design/ExtraDesignClassManager.java @@ -23,6 +23,7 @@ import com.fr.plugin.AbstractExtraClassManager; import com.fr.plugin.injectable.PluginModule; import com.fr.plugin.injectable.PluginSingleInjection; import com.fr.plugin.solution.closeable.CloseableContainedSet; +import com.fr.stable.Filter; import com.fr.stable.plugin.ExtraDesignClassManagerProvider; import java.util.ArrayList; @@ -43,7 +44,7 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement private static ExtraDesignClassManager classManager = new ExtraDesignClassManager(); private Set shortCuts = new CloseableContainedSet<>(HashSet.class); - + public static ExtraDesignClassManager getInstance() { return classManager; } @@ -113,26 +114,39 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement return result.toArray(new WidgetOption[result.size()]); } - public WidgetOption[] getWebWidgetOptions() { + return getWebWidgetOptions(new Filter() { + @Override + public boolean accept(ToolbarItemProvider toolbarItemProvider) { + return true; + } + }); + } + + public WidgetOption[] getWebWidgetOptions(Filter filter) { Set set = getArray(ToolbarItemProvider.XML_TAG); - if (set.isEmpty()) { + return getWebWidgetOptions(set, filter); + } + + public WidgetOption[] getWebWidgetOptions(Set set, Filter filter) { + if (set == null || set.isEmpty()) { return new WidgetOption[0]; } List list = new ArrayList<>(); for (ToolbarItemProvider provider : set) { - WidgetOption option = WidgetOptionFactory.createByWidgetClass( - provider.nameForWidget(), - IOUtils.readIcon(provider.iconPathForWidget()), - provider.classForWidget() - ); - list.add(option); + if (filter != null && filter.accept(provider)) { + WidgetOption option = WidgetOptionFactory.createByWidgetClass( + provider.nameForWidget(), + IOUtils.readIcon(provider.iconPathForWidget()), + provider.classForWidget() + ); + list.add(option); + } } return list.toArray(new WidgetOption[list.size()]); } - public Map, Class> getFormWidgetOptionsMap() { Set set = getArray(FormWidgetOptionProvider.XML_TAG); Map, Class> map = new HashMap<>(); @@ -170,7 +184,6 @@ public class ExtraDesignClassManager extends AbstractExtraClassManager implement } - public WidgetOption[] getCellWidgetOptions() { Set set = getArray(CellWidgetOptionProvider.XML_TAG); if (set.isEmpty()) { diff --git a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java index f9a41e7e4..180e5a50e 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java @@ -3,6 +3,7 @@ package com.fr.design.actions.file; import com.fr.config.Configuration; import com.fr.design.DesignerEnvManager; import com.fr.design.RestartHelper; +import com.fr.design.constants.UIConstants; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.DialogActionAdapter; @@ -28,12 +29,14 @@ import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.design.update.push.DesignerPushUpdateManager; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.widget.FRWidgetFactory; +import com.fr.general.CloudCenter; import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; import com.fr.general.IOUtils; import com.fr.general.Inter; import com.fr.general.log.Log4jConfig; import com.fr.locale.InterProviderFactory; +import com.fr.log.FineLoggerFactory; import com.fr.third.apache.log4j.Level; import com.fr.transaction.Configurations; import com.fr.transaction.Worker; @@ -48,6 +51,8 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; import java.awt.Component; +import java.awt.Cursor; +import java.awt.Desktop; import java.awt.Dimension; import java.awt.Font; import java.awt.Window; @@ -58,6 +63,7 @@ import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; +import java.net.URI; import java.util.Locale; import java.util.Map; @@ -105,6 +111,7 @@ public class PreferencePane extends BasicPane { private static final String DISPLAY_EQUALS = "+"; private static final String MINUS = "MINUS"; private static final String DISPLAY_MINUS = "-"; + private static final String PRIVACY_POLICY = "design.privacy"; private static final Level[] LOG = {Level.FATAL, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG}; @@ -147,6 +154,7 @@ public class PreferencePane extends BasicPane { private UICheckBox useIntervalCheckBox; private IntegerEditor saveIntervalEditor; private UILabel remindVcsLabel; + private UILabel linkLabel; @@ -205,8 +213,27 @@ public class PreferencePane extends BasicPane { JPanel improvePane = FRGUIPaneFactory.createVerticalTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Product_Improve")); joinProductImproveCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Join_Product_Improve")); - improvePane.add(joinProductImproveCheckBox); - + linkLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Privacy_Policy")); + linkLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + linkLabel.setForeground(UIConstants.NORMAL_BLUE); + linkLabel.addMouseListener(new MouseAdapter(){ + @Override + public void mouseClicked(MouseEvent e) { + try { + Desktop.getDesktop().browse(new URI(CloudCenter.getInstance().acquireUrlByKind(PRIVACY_POLICY))); + } catch (Exception e1) { + FineLoggerFactory.getLogger().error(e1.getMessage(), e1); + } + } + }); + double p = TableLayout.PREFERRED; + double rowSize[] = {p}; + double columnSize[] = {p, p}; + Component[][] components = { + {joinProductImproveCheckBox, linkLabel}, + }; + JPanel choosePane = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); + improvePane.add(choosePane); if (DesignerPushUpdateManager.getInstance().isAutoPushUpdateSupported()) { autoPushUpdateCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Automatic_Push_Update")); improvePane.add(autoPushUpdateCheckBox); diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java index ed09c87a8..f6f258285 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java @@ -35,7 +35,7 @@ public class ConnectionTableProcedurePane extends BasicPane { private ConnectionComboBoxPanel connectionComboBox; private UICheckBox tableCheckBox; private UICheckBox viewCheckBox; - private UITextField searchField; + protected UITextField searchField; private TableViewList tableViewList; private java.util.List listeners = new java.util.ArrayList(); @@ -90,12 +90,17 @@ public class ConnectionTableProcedurePane extends BasicPane { this.add(tableViewListPane, BorderLayout.CENTER); this.add(filterPane, BorderLayout.SOUTH); this.setPreferredSize(new Dimension(WIDTH, getPreferredSize().height)); + addKeyMonitor(); } protected void filter(Connection connection, String conName, List nameList) { connection.addConnection(nameList, conName, new Class[]{AbstractDatabaseConnection.class}); } + protected void addKeyMonitor() { + + } + protected JPanel createCheckBoxgroupPane() { JPanel checkBoxgroupPane = FRGUIPaneFactory.createNColumnGridInnerContainer_S_Pane(2); JPanel first = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java index 85b8fbd7d..44b87cad6 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java @@ -57,6 +57,8 @@ import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.List; @@ -95,6 +97,30 @@ public class DBTableDataPane extends AbstractTableDataPane { connection.addConnection(nameList, conName, new Class[]{JDBCDatabaseConnection.class, JNDIDatabaseConnection.class}); } + + @Override + protected void addKeyMonitor() { + searchField.addKeyListener(new KeyListener() { + + @Override + public void keyTyped(KeyEvent e) { + + } + + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + e.setKeyCode(KeyEvent.VK_UP); + DBTableDataPane.this.connectionTableProcedurePane.requestFocus(); + } + } + + @Override + public void keyReleased(KeyEvent e) { + + } + }); + } }; connectionTableProcedurePane.addDoubleClickListener(new DoubleClickSelectedNodeOnTreeListener() { diff --git a/designer-base/src/main/java/com/fr/design/fun/ToolbarItemProvider.java b/designer-base/src/main/java/com/fr/design/fun/ToolbarItemProvider.java index f4add0333..0ba640b26 100644 --- a/designer-base/src/main/java/com/fr/design/fun/ToolbarItemProvider.java +++ b/designer-base/src/main/java/com/fr/design/fun/ToolbarItemProvider.java @@ -1,6 +1,8 @@ package com.fr.design.fun; +import com.fr.design.mainframe.JTemplate; import com.fr.form.ui.Widget; +import com.fr.stable.Filter; import com.fr.stable.fun.mark.Mutable; /** @@ -8,7 +10,7 @@ import com.fr.stable.fun.mark.Mutable; * @since : 8.0 * 自定义web工具栏菜单 */ -public interface ToolbarItemProvider extends Mutable { +public interface ToolbarItemProvider extends Mutable, Filter { String XML_TAG = "ToolbarItemProvider"; @@ -36,4 +38,12 @@ public interface ToolbarItemProvider extends Mutable { */ String nameForWidget(); + /** + * 模板(决策报表 or cpt)是否支持此工具栏按钮 + * JTemplate 模板 + * @return 支持返回true, 否则false + */ + @Override + boolean accept(JTemplate template); + } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractToolbarItem.java b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractToolbarItem.java index ec3c47bc1..49194049a 100644 --- a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractToolbarItem.java +++ b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractToolbarItem.java @@ -1,6 +1,9 @@ package com.fr.design.fun.impl; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.fun.ToolbarItemProvider; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.JVirtualTemplate; import com.fr.stable.fun.impl.AbstractProvider; import com.fr.stable.fun.mark.API; @@ -10,6 +13,7 @@ import com.fr.stable.fun.mark.API; @API(level = ToolbarItemProvider.CURRENT_LEVEL) public abstract class AbstractToolbarItem extends AbstractProvider implements ToolbarItemProvider { + @Override public int currentAPILevel() { return CURRENT_LEVEL; } @@ -18,4 +22,12 @@ public abstract class AbstractToolbarItem extends AbstractProvider implements To public String mark4Provider() { return getClass().getName(); } + + @Override + public boolean accept(JTemplate jTemplate) { + if (jTemplate == null) { + jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + } + return jTemplate == null || jTemplate.isJWorkBook() || jTemplate instanceof JVirtualTemplate; + } } \ No newline at end of file diff --git a/designer-base/src/test/java/com/fr/design/ExtraDesignClassManagerTest.java b/designer-base/src/test/java/com/fr/design/ExtraDesignClassManagerTest.java new file mode 100644 index 000000000..89f4ee1b2 --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/ExtraDesignClassManagerTest.java @@ -0,0 +1,70 @@ +package com.fr.design; + +import com.fr.config.dao.DaoContext; +import com.fr.config.dao.impl.LocalClassHelperDao; +import com.fr.config.dao.impl.LocalEntityDao; +import com.fr.config.dao.impl.LocalXmlEntityDao; +import com.fr.design.fun.ToolbarItemProvider; +import com.fr.design.gui.core.WidgetOption; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.JVirtualTemplate; +import com.fr.general.ModuleContext; +import com.fr.log.FineLoggerFactory; +import com.fr.report.restriction.CellCountRestriction; +import com.fr.report.restriction.ReportRestrictionScene; +import com.fr.restriction.Restrictions; +import com.fr.stable.Filter; +import com.fr.stable.module.Module; +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.junit.Assert; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author zack + * @version 10.0 + * Created by zack on 2019/9/17 + */ +public class ExtraDesignClassManagerTest extends TestCase { + @Override + protected void setUp() throws Exception { + DaoContext.setEntityDao(new LocalEntityDao()); + DaoContext.setClassHelperDao(new LocalClassHelperDao()); + DaoContext.setXmlEntityDao(new LocalXmlEntityDao()); + ModuleContext.startModule(Module.PAGE_MODULE); + Restrictions.register(ReportRestrictionScene.CELL_COUNT, new CellCountRestriction()); + } + + public void testGetWebOption() { + try { + final JTemplate jTemplate = new JVirtualTemplate(null); + ToolbarItemProvider item = EasyMock.mock(ToolbarItemProvider.class); + ToolbarItemProvider item1 = EasyMock.mock(ToolbarItemProvider.class); + EasyMock.expect(item.accept(jTemplate)).andReturn(false).anyTimes(); + EasyMock.expect(item.classForWidget()).andReturn(null).anyTimes(); + EasyMock.expect(item.iconPathForWidget()).andReturn("").anyTimes(); + EasyMock.expect(item.nameForWidget()).andReturn("1").anyTimes(); + EasyMock.expect(item1.accept(jTemplate)).andReturn(true).anyTimes(); + EasyMock.expect(item1.classForWidget()).andReturn(null).anyTimes(); + EasyMock.expect(item1.iconPathForWidget()).andReturn("").anyTimes(); + EasyMock.expect(item1.nameForWidget()).andReturn("2").anyTimes(); + EasyMock.replay(item); + EasyMock.replay(item1); + + Set set = new HashSet<>(); + set.add(item); + set.add(item1); + WidgetOption[] widgetOptions = ExtraDesignClassManager.getInstance().getWebWidgetOptions(set, new Filter() { + @Override + public boolean accept(ToolbarItemProvider toolbarItemProvider) { + return toolbarItemProvider.accept(jTemplate); + } + }); + Assert.assertEquals(1, widgetOptions.length); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/widget/accessibles/AccessibleElementCaseToolBarEditor.java b/designer-form/src/main/java/com/fr/design/mainframe/widget/accessibles/AccessibleElementCaseToolBarEditor.java index 0fcf1e25b..de429b414 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/widget/accessibles/AccessibleElementCaseToolBarEditor.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/widget/accessibles/AccessibleElementCaseToolBarEditor.java @@ -1,13 +1,17 @@ package com.fr.design.mainframe.widget.accessibles; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.fun.ToolbarItemProvider; import com.fr.design.gui.core.WidgetOption; import com.fr.design.mainframe.FormWebWidgetConstants; import com.fr.design.mainframe.widget.editors.ElementCaseToolBarPane; import com.fr.design.mainframe.widget.wrappers.ElementCaseToolBarWrapper; import com.fr.form.web.FormToolBarManager; import com.fr.stable.ArrayUtils; +import com.fr.stable.Filter; import javax.swing.SwingUtilities; import java.util.ArrayList; @@ -52,6 +56,13 @@ public class AccessibleElementCaseToolBarEditor extends UneditableAccessibleEdit List defaultOptions = Arrays.asList(FormWebWidgetConstants.getFormElementCaseToolBarInstance()); List options = new ArrayList(); options.addAll(defaultOptions); + WidgetOption[] widgetOptions = ExtraDesignClassManager.getInstance().getWebWidgetOptions(new Filter() { + @Override + public boolean accept(ToolbarItemProvider toolbarItemProvider) { + return toolbarItemProvider.accept(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()); + } + }); + options.addAll(Arrays.asList(widgetOptions)); return options.toArray(new WidgetOption[options.size()]); } diff --git a/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java b/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java index a48d64fdc..5f45b57b0 100644 --- a/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java @@ -24,6 +24,7 @@ import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.widget.accessibles.AccessibleBackgroundEditor; import com.fr.design.utils.gui.UIComponentUtils; import com.fr.design.widget.ui.designer.AbstractDataModify; +import com.fr.design.widget.ui.designer.component.UIBoundSpinner; import com.fr.form.ui.container.WParameterLayout; import com.fr.general.Background; @@ -61,7 +62,7 @@ public class RootDesignDefinePane extends AbstractDataModify { public void initComponent() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); - designerWidth = new UISpinner(1, Integer.MAX_VALUE, 1); + designerWidth = new UIBoundSpinner(1, Integer.MAX_VALUE, 1); JPanel advancePane = createAdvancePane(); UIExpandablePane advanceExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, advancePane); this.add(advanceExpandablePane, BorderLayout.NORTH); @@ -162,16 +163,29 @@ public class RootDesignDefinePane extends AbstractDataModify { public WParameterLayout updateBean() { WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); wParameterLayout.setLabelName(labelNameTextField.getText()); - wParameterLayout.setDesignWidth((int) designerWidth.getValue()); + if (isCompsOutOfDesignerWidth((int) designerWidth.getValue())) { + designerWidth.setValue(wParameterLayout.getDesignWidth()); + } else { + wParameterLayout.setDesignWidth((int) designerWidth.getValue()); + } wParameterLayout.setDelayDisplayContent(displayReport.isSelected()); wParameterLayout.setUseParamsTemplate(useParamsTemplate.isSelected()); JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); wParameterLayout.setBackground((Background) background.getValue()); - wParameterLayout.setPosition((int)hAlignmentPane.getSelectedItem()); + wParameterLayout.setPosition((int) hAlignmentPane.getSelectedItem()); return wParameterLayout; } + private boolean isCompsOutOfDesignerWidth(int designerWidth){ + for(int i=0; i designerWidth){ + return true; + } + } + return false; + } @Override public DataCreatorUI dataUI() { return null; diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/InformationCollector.java b/designer-realize/src/main/java/com/fr/design/mainframe/InformationCollector.java index 83cb7dd33..7c3ca2dac 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/InformationCollector.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/InformationCollector.java @@ -1,13 +1,12 @@ -/** - * - */ package com.fr.design.mainframe; import com.fr.base.FRContext; +import com.fr.concurrent.NamedThreadFactory; import com.fr.config.MarketConfig; import com.fr.design.DesignerEnvManager; import com.fr.design.mainframe.errorinfo.ErrorInfoUploader; import com.fr.design.mainframe.messagecollect.impl.FocusPointMessageUploader; +import com.fr.design.mainframe.messagecollect.solid.SolidCollector; import com.fr.design.mainframe.template.info.TemplateInfoCollector; import com.fr.general.CloudCenter; import com.fr.general.ComparatorUtils; @@ -29,6 +28,7 @@ import com.fr.stable.xml.XMLTools; import com.fr.stable.xml.XMLWriter; import com.fr.stable.xml.XMLableReader; import com.fr.third.javax.xml.stream.XMLStreamException; +import com.sun.management.OperatingSystemMXBean; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; @@ -42,6 +42,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; +import java.lang.management.ManagementFactory; +import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; @@ -52,15 +54,19 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** - * @author neil + * 设计器信息收集 * + * @author neil * @date: 2015-4-8-下午5:11:46 */ public class InformationCollector implements XMLReadable, XMLWriter { - // 24小时上传一次 + /** + * 24小时上传一次 + */ private static final long DELTA = 24 * 3600 * 1000L; private static final long SEND_DELAY = 300 * 1000L; + private static final int BYTE_TO_MB = 1024 * 1024; private static final String FILE_NAME = "fr.info"; private static final String XML_START_STOP_LIST = "StartStopList"; private static final String XML_START_STOP = "StartStop"; @@ -73,26 +79,33 @@ public class InformationCollector implements XMLReadable, XMLWriter { private static final String XML_UUID = "UUID"; private static final String XML_KEY = "ActiveKey"; private static final String XML_OS = "OS"; + private static final String XML_ARCH = "arch"; + private static final String XML_AVAILABLE_PROCESSORS = "cpu"; + private static final String XML_PHYSICAL_MEMORY = "systemMemory"; private static InformationCollector collector; - //启动时间与关闭时间列表 - private List startStop = new ArrayList(); - //上一次的发送时间 + /** + * 启动时间与关闭时间列表 + */ + private List startStop = new ArrayList<>(); + /** + * 上一次的发送时间 + */ private String lastTime; private StartStopTime current = new StartStopTime(); - public static InformationCollector getInstance(){ + public static InformationCollector getInstance() { if (collector == null) { collector = new InformationCollector(); - readEncodeXMLFile(collector, collector.getInfoFile()); + readEncodeXMLFile(collector, collector.getInfoFile()); } return collector; } - private static void readEncodeXMLFile(XMLReadable xmlReadable, File xmlFile){ + private static void readEncodeXMLFile(XMLReadable xmlReadable, File xmlFile) { if (xmlFile == null || !xmlFile.exists()) { return; } @@ -118,13 +131,13 @@ public class InformationCollector implements XMLReadable, XMLWriter { } - private static String getDecodeFileContent(File xmlFile) throws FileNotFoundException, UnsupportedEncodingException{ + private static String getDecodeFileContent(File xmlFile) throws FileNotFoundException, UnsupportedEncodingException { InputStream encodeInputStream = new FileInputStream(xmlFile); String encodeContent = IOUtils.inputStream2String(encodeInputStream); return DesUtils.getDecString(encodeContent); } - private long getLastTimeMillis(){ + private long getLastTimeMillis() { if (StringUtils.isEmpty(this.lastTime)) { return 0; } @@ -141,23 +154,36 @@ public class InformationCollector implements XMLReadable, XMLWriter { JSONObject content = new JSONObject(); JSONArray startStopArray = new JSONArray(); - for (int i = 0; i < startStop.size(); i++) { + for (StartStopTime startStopTime : startStop) { JSONObject jo = new JSONObject(); - jo.put(ATTR_START, startStop.get(i).getStartDate()); - jo.put(ATTR_STOP, startStop.get(i).getStopDate()); + jo.put(ATTR_START, startStopTime.getStartDate()); + jo.put(ATTR_STOP, startStopTime.getStopDate()); startStopArray.put(jo); - DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); - content.put(XML_START_STOP, startStopArray); - content.put(XML_UUID, envManager.getUUID()); - content.put(XML_JAR, GeneralUtils.readBuildNO()); - content.put(XML_VERSION, ProductConstants.RELEASE_VERSION); - content.put(XML_USERNAME, MarketConfig.getInstance().getBbsUsername()); - content.put(XML_KEY, envManager.getActivationKey()); - content.put(XML_OS, System.getProperty("os.name")); } + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + content.put(XML_START_STOP, startStopArray); + content.put(XML_UUID, envManager.getUUID()); + content.put(XML_JAR, GeneralUtils.readBuildNO()); + content.put(XML_VERSION, ProductConstants.RELEASE_VERSION); + content.put(XML_USERNAME, MarketConfig.getInstance().getBbsUsername()); + content.put(XML_KEY, envManager.getActivationKey()); + content.put(XML_OS, System.getProperty("os.name")); + content.put(XML_ARCH, System.getProperty("os.arch")); + content.put(XML_AVAILABLE_PROCESSORS, Runtime.getRuntime().availableProcessors()); + content.put(XML_PHYSICAL_MEMORY, getTotalPhysicalMemorySize()); return content; } + /** + * 获取物理内存,单位GB + * + * @return 物理内存 + */ + private static long getTotalPhysicalMemorySize() { + OperatingSystemMXBean bean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); + return bean.getTotalPhysicalMemorySize() / BYTE_TO_MB; + } + private void sendUserInfo(){ long currentTime = new Date().getTime(); long lastTime = getLastTimeMillis(); @@ -185,21 +211,22 @@ public class InformationCollector implements XMLReadable, XMLWriter { /** * 收集开始使用时间,发送信息 */ - public void collectStartTime(){ + public void collectStartTime() { this.current.setStartDate(dateToString()); sendUserInfoInOtherThread(); } - private void sendUserInfoInOtherThread(){ + private void sendUserInfoInOtherThread() { if (!DesignerEnvManager.getEnvManager().isJoinProductImprove() || !FRContext.isChineseEnv()) { return; } - ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); + ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("InformationCollector")); service.schedule(new Runnable() { @Override public void run() { + SolidCollector.getInstance().sendToCloudCenterAndDeleteFile(); sendUserInfo(); FocusPointMessageUploader.getInstance().sendToCloudCenter(); TemplateInfoCollector.getInstance().sendTemplateInfo(); @@ -208,67 +235,66 @@ public class InformationCollector implements XMLReadable, XMLWriter { }, SEND_DELAY, TimeUnit.MILLISECONDS); } - /** - * 收集结束使用时间 - */ - public void collectStopTime(){ + /** + * 收集结束使用时间 + */ + public void collectStopTime() { this.current.setStopDate(dateToString()); } - private String dateToString(){ + private String dateToString() { DateFormat df = FRContext.getDefaultValues().getDateTimeFormat(); return df.format(new Date()); } - private void reset(){ + private void reset() { this.startStop.clear(); this.lastTime = dateToString(); } - private File getInfoFile() { - return new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FILE_NAME)); - } - - /** - * 保存xml文件 - */ - public void saveXMLFile() { - File xmlFile = this.getInfoFile(); - try{ - ByteArrayOutputStream out = new ByteArrayOutputStream(); + private File getInfoFile() { + return new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FILE_NAME)); + } + + /** + * 保存xml文件 + */ + public void saveXMLFile() { + File xmlFile = this.getInfoFile(); + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); XMLTools.writeOutputStreamXML(this, out); out.flush(); out.close(); - String fileContent = new String(out.toByteArray(), EncodeConstants.ENCODING_UTF_8); + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); String encodeCotent = DesUtils.getEncString(fileContent); writeEncodeContentToFile(encodeCotent, xmlFile); - }catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); } - } + } /** * 将文件内容写到输出流中 */ - private static void writeEncodeContentToFile(String fileContent, File file){ + private static void writeEncodeContentToFile(String fileContent, File file) { BufferedWriter bw = null; try { FileOutputStream fos = new FileOutputStream(file); - OutputStreamWriter osw = new OutputStreamWriter(fos, EncodeConstants.ENCODING_UTF_8); + OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); bw = new BufferedWriter(osw); bw.write(fileContent); } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineLoggerFactory.getLogger().error(e.getMessage(), e); } finally { - if(bw != null){ + if (bw != null) { try { bw.close(); - } catch (IOException e) { + } catch (IOException ignore) { } } } - } @Override @@ -283,56 +309,57 @@ public class InformationCollector implements XMLReadable, XMLWriter { writer.end(); } - private void writeStartStopList(XMLPrintWriter writer){ + private void writeStartStopList(XMLPrintWriter writer) { //启停 - writer.startTAG(XML_START_STOP_LIST); - for (int i = 0; i < startStop.size(); i++) { - startStop.get(i).writeXML(writer); + writer.startTAG(XML_START_STOP_LIST); + for (StartStopTime startStopTime : startStop) { + startStopTime.writeXML(writer); } - writer.end(); + writer.end(); } - private void writeTag(String tag, String content, XMLPrintWriter writer){ + private void writeTag(String tag, String content, XMLPrintWriter writer) { if (StringUtils.isEmpty(content)) { return; } - writer.startTAG(tag); - writer.textNode(content); - writer.end(); + writer.startTAG(tag); + writer.textNode(content); + writer.end(); } @Override public void readXML(XMLableReader reader) { - if (reader.isChildNode()) { - String name = reader.getTagName(); - if (XML_START_STOP_LIST.equals(name)) { - readStartStopList(reader); - } else if(XML_LAST_TIME.equals(name)){ - readLastTime(reader); + if (reader.isChildNode()) { + String name = reader.getTagName(); + if (XML_START_STOP_LIST.equals(name)) { + readStartStopList(reader); + } else if (XML_LAST_TIME.equals(name)) { + readLastTime(reader); } - } + } } - private void readLastTime(XMLableReader reader){ + private void readLastTime(XMLableReader reader) { String tmpVal; if (StringUtils.isNotBlank(tmpVal = reader.getElementValue())) { this.lastTime = tmpVal; } } - private void readStartStopList(XMLableReader reader){ - startStop.clear(); + private void readStartStopList(XMLableReader reader) { + startStop.clear(); reader.readXMLObject(new XMLReadable() { - public void readXML(XMLableReader reader) { - if (XML_START_STOP.equals(reader.getTagName())) { - StartStopTime startStopTime = new StartStopTime(); - reader.readXMLObject(startStopTime); - startStop.add(startStopTime); - } - } - }); + @Override + public void readXML(XMLableReader reader) { + if (XML_START_STOP.equals(reader.getTagName())) { + StartStopTime startStopTime = new StartStopTime(); + reader.readXMLObject(startStopTime); + startStop.add(startStopTime); + } + } + }); } private class StartStopTime implements XMLReadable, XMLWriter { @@ -356,17 +383,19 @@ public class InformationCollector implements XMLReadable, XMLWriter { this.stopDate = endDate; } + @Override public void writeXML(XMLPrintWriter writer) { - writer.startTAG(XML_START_STOP); - if (StringUtils.isNotEmpty(startDate)) { - writer.attr(ATTR_START, this.startDate); + writer.startTAG(XML_START_STOP); + if (StringUtils.isNotEmpty(startDate)) { + writer.attr(ATTR_START, this.startDate); } - if (StringUtils.isNotEmpty(stopDate)) { - writer.attr(ATTR_STOP, this.stopDate); + if (StringUtils.isNotEmpty(stopDate)) { + writer.attr(ATTR_STOP, this.stopDate); } - writer.end(); + writer.end(); } + @Override public void readXML(XMLableReader reader) { this.startDate = reader.getAttrAsString(ATTR_START, StringUtils.EMPTY); this.stopDate = reader.getAttrAsString(ATTR_STOP, StringUtils.EMPTY); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartupMessageCollector.java b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartupMessageCollector.java new file mode 100644 index 000000000..288cac400 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartupMessageCollector.java @@ -0,0 +1,92 @@ +package com.fr.design.mainframe.messagecollect; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.DesignerEnvManager; +import com.fr.design.mainframe.SiteCenterToken; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; +import com.fr.general.CloudCenter; +import com.fr.general.ComparatorUtils; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.module.ModuleContext; +import com.fr.module.engine.FineModule; +import com.fr.runtime.FineRuntime; +import com.fr.stable.StringUtils; + +import java.util.HashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * 启动信息收集 + * + * @author vito + * @version 10.0 + * Created by vito on 2019/9/4 + */ +public class StartupMessageCollector { + + private static final String XML_STARTUP_TIME = "t"; + private static final String XML_STARTUP_LOG = "startupLog"; + private static final String XML_STARTUP_Memory = "designerMemory"; + private static final String XML_STARTUP_COST = "cost"; + private static final String XML_UUID = "UUID"; + private static final String STARTUP_URL_KEY = "user.info.v10.startup"; + private static final String LOG_TYPE = "single"; + private static final int BYTE_TO_MB = 1024 * 1024; + + public static final StartupMessageCollector INSTANCE = new StartupMessageCollector(); + + private StartupMessageCollector() { + } + + public static StartupMessageCollector getInstance() { + return INSTANCE; + } + + public void recordStartupLog() { + EventDispatcher.listen(FineRuntime.ApplicationEvent.AFTER_START, new Listener() { + + @Override + public void on(Event event, Long param) { + final String url = CloudCenter.getInstance().acquireUrlByKind(STARTUP_URL_KEY); + if (StringUtils.isEmpty(url)) { + return; + } + ExecutorService es = Executors.newSingleThreadExecutor(new NamedThreadFactory("StartupMessageCollector")); + es.submit(new Runnable() { + @Override + public void run() { + FineModule root = (FineModule) ModuleContext.getRoot().getRoot(); + JSONObject profile = root.profile(); + JSONObject json = JSONObject.create() + .put(XML_UUID, DesignerEnvManager.getEnvManager().getUUID()) + .put(XML_STARTUP_TIME, FineRuntime.getAppStartTime() + FineRuntime.getStartingTime()) + .put(XML_STARTUP_COST, FineRuntime.getStartingTime()) + .put(XML_STARTUP_LOG, profile) + .put(XML_STARTUP_Memory, Runtime.getRuntime().totalMemory() / BYTE_TO_MB); + sendInfo(json, url + LOG_TYPE); + } + }); + es.shutdown(); + } + }); + } + + private boolean sendInfo(JSONObject content, String url) { + boolean success = false; + try { + HashMap para = new HashMap<>(); + para.put("token", SiteCenterToken.generateToken()); + para.put("content", content); + String res = HttpToolbox.post(url, para); + success = ComparatorUtils.equals(new JSONObject(res).get("status"), "success"); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return success; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/solid/SolidCollectConstants.java b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/solid/SolidCollectConstants.java new file mode 100644 index 000000000..452da9ecc --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/solid/SolidCollectConstants.java @@ -0,0 +1,18 @@ +package com.fr.design.mainframe.messagecollect.solid; + +/** + * Created by alex sung on 2019/9/5. + */ +public class SolidCollectConstants { + private SolidCollectConstants(){} + + /** + * 客户端请求subject + */ + public static final String REQUEST_SUBJECT = "solid"; + + /** + * 客户端请求超时鉴权时间,默认1h失效 + */ + public static final long TIME_OUT = 60 * 60 * 1000; +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/solid/SolidCollector.java b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/solid/SolidCollector.java new file mode 100644 index 000000000..68cc882a9 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/solid/SolidCollector.java @@ -0,0 +1,97 @@ +package com.fr.design.mainframe.messagecollect.solid; + +import com.fr.general.CloudCenter; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSON; +import com.fr.json.JSONFactory; +import com.fr.log.FineLoggerFactory; +import com.fr.security.JwtUtils; +import com.fr.stable.CommonUtils; +import com.fr.stable.StringUtils; +import com.fr.workspace.WorkContext; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static com.fr.design.mainframe.messagecollect.solid.SolidCollectConstants.REQUEST_SUBJECT; +import static com.fr.design.mainframe.messagecollect.solid.SolidCollectConstants.TIME_OUT; + +/** + * 设计器固化信息回传类 + * Created by alex sung on 2019/8/22. + */ + + +public class SolidCollector { + private static final String CONTENT_URL = "/v10/collect/solid"; + private static final String DELETE_URL = "/v10/collect/solid/delete"; + private static final String UNLOCK_URL = "/v10/collect/solid/unlock"; + private static final String ATTR_CIPHER_TEXT = "cipherText"; + private static final String ATTR_SIGNATURE = "signature"; + private static final String SOLID_UPLOAD_URL = CloudCenter.getInstance().acquireUrlByKind("design.solid"); + + private static volatile SolidCollector instance; + + public static SolidCollector getInstance() { + if (instance == null) { + synchronized (SolidCollector.class) { + if (instance == null) { + instance = new SolidCollector(); + } + } + } + return instance; + } + + /** + * 回传文件给云中心,并删除服务端本地文件 + */ + public void sendToCloudCenterAndDeleteFile() { + if (WorkContext.getCurrent().isLocal()) { + return; + } + FineLoggerFactory.getLogger().info("start to get solid content from server..."); + try { + String content = requestContent(); + if (StringUtils.isNotEmpty(content)) { + String cipherText = JSONFactory.createJSON(JSON.OBJECT, content).optString("data"); + if(StringUtils.isNotEmpty(cipherText)){ + Map params = new HashMap<>(); + params.put(ATTR_CIPHER_TEXT, cipherText); + params.put(ATTR_SIGNATURE, String.valueOf(CommonUtils.signature())); + HttpToolbox.post(SOLID_UPLOAD_URL, params); + + String deleteUrl = WorkContext.getCurrent().getPath() + DELETE_URL; + HttpToolbox.post(deleteUrl, getParams()); + } + } + FineLoggerFactory.getLogger().info("send solid content to cloud center success."); + } catch (Exception e) { + FineLoggerFactory.getLogger().info(e.getMessage(), e); + } finally { + String unlockUrl = WorkContext.getCurrent().getPath() + UNLOCK_URL; + try { + HttpToolbox.post(unlockUrl, getParams()); + } catch (IOException e) { + FineLoggerFactory.getLogger().warn(e.getMessage(), e); + } + } + } + + /** + * 获取服务端固化文件内容 + * @return 回传内容 + */ + public String requestContent() throws Exception { + Map params = new HashMap(); + params.put("token", JwtUtils.createDefaultJWT(REQUEST_SUBJECT, TIME_OUT)); + return HttpToolbox.get(WorkContext.getCurrent().getPath() + CONTENT_URL, params); + } + + private Map getParams() { + Map params = new HashMap(); + params.put("token", JwtUtils.createDefaultJWT(REQUEST_SUBJECT, TIME_OUT)); + return params; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/write/submit/SmartInsertDBManipulationPane.java b/designer-realize/src/main/java/com/fr/design/write/submit/SmartInsertDBManipulationPane.java index f9433aade..dd675ffe3 100644 --- a/designer-realize/src/main/java/com/fr/design/write/submit/SmartInsertDBManipulationPane.java +++ b/designer-realize/src/main/java/com/fr/design/write/submit/SmartInsertDBManipulationPane.java @@ -27,6 +27,7 @@ import com.fr.design.selection.SelectionListener; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.FloatSelection; import com.fr.grid.selection.Selection; +import com.fr.report.cell.TemplateCellElement; import com.fr.stable.ColumnRow; import com.fr.stable.ColumnRowGroup; import com.fr.stable.StringUtils; @@ -454,11 +455,22 @@ public class SmartInsertDBManipulationPane extends DBManipulationPane { newAdd.clear(); for (int i = 0; i < cs; i++) { for (int j = 0; j < rs; j++) { - ColumnRow columnRow = ColumnRow.valueOf(c + i, r + j); - if (!allColumnRow.contains(columnRow.toString())) { - add.addColumnRow(columnRow); + TemplateCellElement cellElement = ePane.getEditingElementCase().getTemplateCellElement(c + i, r + j ); + if (cellElement != null && ((i + c) != 0 || (r + j) != 0)) { + String value = cellElement.toString(); + if (!newAdd.contains(value) && !allColumnRow.contains(value)) { + add.addColumnRow(ColumnRow.valueOf(value)); + } + newAdd.add(value); + } + + if (cellElement == null) { + ColumnRow columnRow = ColumnRow.valueOf(c + i, r + j); + if (!allColumnRow.contains(columnRow.toString())) { + add.addColumnRow(columnRow); + } + newAdd.add(columnRow.toString()); } - newAdd.add(columnRow.toString()); } } int oldSize = oldAdd.size(); diff --git a/designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellFormulaQuickEditor.java b/designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellFormulaQuickEditor.java index 713f9ac3d..ff8a74e57 100644 --- a/designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellFormulaQuickEditor.java +++ b/designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellFormulaQuickEditor.java @@ -103,7 +103,7 @@ public class CellFormulaQuickEditor extends CellQuickEditor { formulaButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { String text = formulaTextField.getText(); - final UIFormula formulaPane = FormulaFactory.createFormulaPane(); + final UIFormula formulaPane = FormulaFactory.createFormulaPaneWhenReserveFormula(); formulaPane.populate(BaseFormula.createFormulaBuilder().build(text)); formulaPane.showLargeWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { @Override diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java index 4a3db7b2c..5f8fe7023 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java @@ -1,14 +1,15 @@ package com.fr.start.module; +import com.fr.concurrent.NamedThreadFactory; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.messagecollect.StartupMessageCollector; import com.fr.event.Event; import com.fr.event.Listener; import com.fr.module.Activator; import com.fr.record.analyzer.EnableMetrics; import com.fr.record.analyzer.Metrics; -import com.fr.runtime.FineRuntime; import com.fr.start.Designer; import com.fr.start.ServerStarter; import com.fr.start.SplashContext; @@ -42,7 +43,7 @@ public class DesignerStartup extends Activator { startSub(EnvBasedModule.class); //designer模块启动好后,查看demo browserDemo(); - ExecutorService service = Executors.newFixedThreadPool(2); + ExecutorService service = Executors.newSingleThreadExecutor(new NamedThreadFactory("FineEmbedServerStart")); service.submit(new Runnable() { @Override public void run() { @@ -67,7 +68,7 @@ public class DesignerStartup extends Activator { DesignerContext.getDesignerFrame().getProgressDialog().setVisible(true); startSub(StartFinishActivator.class); - FineRuntime.startFinish(); + StartupMessageCollector.getInstance().recordStartupLog(); } private void browserDemo() { @@ -87,7 +88,7 @@ public class DesignerStartup extends Activator { @Override public void on(Event event, Workspace current) { - getSub(EnvBasedModule.class).stop(); + stopSub(EnvBasedModule.class); } }); /*切换环境后,重新启动所有相关模块,最先执行*/ @@ -95,7 +96,7 @@ public class DesignerStartup extends Activator { @Override public void on(Event event, Workspace current) { - getSub(EnvBasedModule.class).start(); + startSub(EnvBasedModule.class); // 切换后的环境是本地环境才启动内置服务器 if (current.isLocal()) { ExecutorService service = Executors.newSingleThreadExecutor();