diff --git a/.gitignore b/.gitignore index 417bed08c8..b3c7613a58 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,14 @@ .DS_Store .classpath .project +.gradle target/ +*/build + +designer-base/${web-inf-path} +designer-chart/${web-inf-path} +designer-form/${web-inf-path} +designer-realize/${web-inf-path} + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..0112687676 --- /dev/null +++ b/build.gradle @@ -0,0 +1,82 @@ +import org.gradle.plugins.ide.idea.model.IdeaLanguageLevel + +plugins { + id 'java' + id 'java-library' + id 'com.fr.common' version '1.0-SNAPSHOT' +} + +// 模块参数 +ext { + frVersion = "" + outputPath = "build" + ignoreTestFailureSetting = true + languageLevelSetting = 1.8 +} + +applyGlobalConfigPathIfExist() + +if (versions.frVersion) { + frVersion = versions.frVersion +} +def frDevVersion = "DEV" + frVersion + +dependencies { + api project(':designer-base') + api project(':designer-chart') + api project(':designer-form') + api project(':designer-realize') +} + +allprojects { + apply plugin: 'java' + apply plugin: 'java-library' + apply plugin: 'idea' + + group 'com.fr.design' + version frDevVersion + sourceCompatibility = languageLevelSetting + targetCompatibility = languageLevelSetting + + tasks.withType(JavaCompile) { + options.encoding = "UTF-8" + } + + repositories { + mavenLocal() + } + + idea { + module { + inheritOutputDirs = false + outputDir = file(outputPath +"/classes") + testOutputDir = file(outputPath +"/test-classes") + languageLevel = new IdeaLanguageLevel(sourceCompatibility) + targetBytecodeVersion = targetCompatibility + } + } + + dependencies { + implementation 'com.fr.third:jxbrowser:7.5' + implementation 'com.fr.third:jxbrowser-swing:7.5' + implementation 'com.fr.third:jxbrowser-mac:7.5' + implementation 'com.fr.third:jxbrowser-win64:7.5' + implementation 'com.fr.third.server:servlet-api:3.0' + implementation 'org.swingexplorer:swexpl:2.0.1' + implementation 'org.swingexplorer:swag:1.0' + implementation 'net.java.dev.jna:jna:5.4.0' + implementation 'org.apache.tomcat:tomcat-catalina:8.5.32' + implementation 'io.socket:socket.io-client:0.7.0' + implementation 'com.fr.third:fine-third:' + frVersion + implementation 'com.fr.core:fine-core:' + frVersion + implementation 'com.fr.activator:fine-activator:' + frVersion + implementation 'com.fr.datasource:fine-datasource:' + frVersion + implementation 'com.fr.decision:fine-decision:' + frVersion + implementation 'com.fr.schedule:fine-schedule:' + frVersion + implementation 'com.fr.report:fine-report-engine:' + frDevVersion + testImplementation 'org.easymock:easymock:3.5.1' + testImplementation 'org.powermock:powermock-module-junit4:1.7.1' + testImplementation 'org.powermock:powermock-api-easymock:1.7.1' + testImplementation 'junit:junit:4.12' + } +} diff --git a/designer-base/src/main/java/com/fr/design/bridge/exec/JSExecutor.java b/designer-base/src/main/java/com/fr/design/bridge/exec/JSExecutor.java index 9ded472eb3..1efa613abc 100644 --- a/designer-base/src/main/java/com/fr/design/bridge/exec/JSExecutor.java +++ b/designer-base/src/main/java/com/fr/design/bridge/exec/JSExecutor.java @@ -4,5 +4,8 @@ package com.fr.design.bridge.exec; * Created by ibm on 2017/6/21. */ public interface JSExecutor { + + String CALLBACK_FUNCTION_NAME = "action"; + void executor(String newValue); } diff --git a/designer-base/src/main/java/com/fr/design/dcm/UniversalDatabasePane.java b/designer-base/src/main/java/com/fr/design/dcm/UniversalDatabasePane.java index e29a9f6698..f16fa0b11d 100644 --- a/designer-base/src/main/java/com/fr/design/dcm/UniversalDatabasePane.java +++ b/designer-base/src/main/java/com/fr/design/dcm/UniversalDatabasePane.java @@ -2,9 +2,8 @@ package com.fr.design.dcm; import com.fr.design.dialog.BasicPane; import com.fr.design.ui.ModernUIPane; -import com.teamdev.jxbrowser.chromium.JSValue; -import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; -import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; +import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; +import com.teamdev.jxbrowser.js.JsObject; import java.awt.*; @@ -26,14 +25,13 @@ public class UniversalDatabasePane extends BasicPane { setLayout(new BorderLayout()); modernUIPane = new ModernUIPane.Builder<>() .withComponent(UniversalDatabaseComponent.KEY) - .prepare(new ScriptContextAdapter() { - @Override - public void onScriptContextCreated(ScriptContextEvent event) { - JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window"); - window.asObject().setProperty("DcmHelper", UniversalDcmBridge.getBridge(event.getBrowser())); + .prepare(params -> { + JsObject window = params.frame().executeJavaScript("window"); + if (window != null) { + window.putProperty("DcmHelper", UniversalDcmBridge.getBridge()); } - }) - .build(); + return InjectJsCallback.Response.proceed(); + }).build(); add(modernUIPane, BorderLayout.CENTER); } } diff --git a/designer-base/src/main/java/com/fr/design/dcm/UniversalDcmBridge.java b/designer-base/src/main/java/com/fr/design/dcm/UniversalDcmBridge.java index 577acada97..db43c3c79d 100644 --- a/designer-base/src/main/java/com/fr/design/dcm/UniversalDcmBridge.java +++ b/designer-base/src/main/java/com/fr/design/dcm/UniversalDcmBridge.java @@ -2,8 +2,6 @@ package com.fr.design.dcm; import com.fr.decision.webservice.bean.BaseBean; import com.fr.design.bridge.exec.JSBridge; -import com.teamdev.jxbrowser.chromium.Browser; -import com.teamdev.jxbrowser.chromium.JSObject; /** * @author richie @@ -13,18 +11,18 @@ import com.teamdev.jxbrowser.chromium.JSObject; */ public class UniversalDcmBridge { - public static UniversalDcmBridge getBridge(Browser browser) { - return new UniversalDcmBridge(browser); + public static UniversalDcmBridge getBridge() { + return new UniversalDcmBridge(); } - private JSObject window; - private UniversalDcmBridge(Browser browser) { - this.window = browser.executeJavaScriptAndReturnValue("window").asObject(); + private UniversalDcmBridge() { + } /** * 获取所有的数据连接 + * * @return 数据连接集合 */ @JSBridge diff --git a/designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java b/designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java index 471e25109a..0862c74472 100644 --- a/designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java +++ b/designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java @@ -196,18 +196,6 @@ public class LoginWebBridge { uiLabel.setBackground(LOGIN_BACKGROUND); } - /** - * 弹出QQ授权页面 - */ - public void showQQ() { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - WebViewDlgHelper.createQQLoginDialog(); - } - }); - } - /** * 关闭QQ授权窗口 */ diff --git a/designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java b/designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java index 10f65fa2b7..159e6d6d9c 100644 --- a/designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java +++ b/designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java @@ -533,13 +533,6 @@ public class PluginWebBridge { threadPoolExecutor.submit(task); } - /** - * 弹出QQ授权页面 - */ - public void showQQ() { - LoginWebBridge.getHelper().showQQ(); - } - /** * 通过QQ登录后通知登录 */ diff --git a/designer-base/src/main/java/com/fr/design/extra/QQLoginWebPane.java b/designer-base/src/main/java/com/fr/design/extra/QQLoginWebPane.java deleted file mode 100644 index 9c56738b49..0000000000 --- a/designer-base/src/main/java/com/fr/design/extra/QQLoginWebPane.java +++ /dev/null @@ -1,234 +0,0 @@ -package com.fr.design.extra; - -import com.fr.design.dialog.FineJOptionPane; -import com.fr.general.CloudCenter; -import com.fr.general.ComparatorUtils; -import com.fr.general.IOUtils; -import com.fr.log.FineLoggerFactory; -import javafx.application.Platform; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; -import javafx.concurrent.Worker; -import javafx.embed.swing.JFXPanel; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.Scene; -import javafx.scene.control.ButtonBuilder; -import javafx.scene.control.LabelBuilder; -import javafx.scene.input.MouseEvent; -import javafx.scene.layout.BorderPane; -import javafx.scene.layout.HBox; -import javafx.scene.layout.HBoxBuilder; -import javafx.scene.paint.Color; -import javafx.scene.web.WebEngine; -import javafx.scene.web.WebEvent; -import javafx.scene.web.WebView; -import javafx.stage.Modality; -import javafx.stage.Screen; -import javafx.stage.Stage; -import javafx.stage.StageStyle; -import javafx.stage.WindowEvent; -import javafx.util.Callback; -import netscape.javascript.JSObject; - -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; -import java.awt.Toolkit; - -/** - * Created by zhaohehe on 16/7/28. - */ -public class QQLoginWebPane extends JFXPanel { - - private WebEngine webEngine; - private String url; - - private static JSObject window; - - private static int DEFAULT_PRIMARYSTAGE_WIDTH = 100; - private static int DEFAULT_PRIMARYSTAGE_HEIGHT = 100; - - private static int DEFAULT_CONFIRM_WIDTH = 450; - private static int DEFAULT_CONFIRM_HEIGHT = 160; - private static int DEFAULT_OFFEST = 20; - - class Delta { - double x, y; - } - - public QQLoginWebPane(final String installHome) { - Platform.setImplicitExit(false); - Platform.runLater(new Runnable() { - @Override - public void run() { - BorderPane root = new BorderPane(); - Scene scene = new Scene(root); - QQLoginWebPane.this.setScene(scene); - final WebView webView = new WebView(); - webEngine = webView.getEngine(); - url = "file:///" + installHome + "/scripts/qqLogin.html"; - webEngine.load(url); - - final Stage primaryStage = new Stage(); - - HBox layout = new HBox(); - try { - primaryStage.initStyle(StageStyle.TRANSPARENT); - primaryStage.setScene(new Scene(layout)); - webView.getScene().getStylesheets().add(IOUtils.getResource("modal-dialog.css", getClass()).toExternalForm()); - primaryStage.initStyle(StageStyle.UTILITY); - primaryStage.setScene(new Scene(new Group(), DEFAULT_PRIMARYSTAGE_WIDTH, DEFAULT_PRIMARYSTAGE_HEIGHT)); - primaryStage.setX(0); - primaryStage.setY(Screen.getPrimary().getBounds().getHeight() + DEFAULT_PRIMARYSTAGE_HEIGHT); - primaryStage.show(); - } catch (Exception e) { - FineLoggerFactory.getLogger().info(e.getMessage()); - } - webEngine.setConfirmHandler(new Callback() { - @Override - public Boolean call(String msg) { - Boolean confirmed = confirm(primaryStage, msg, webView); - return confirmed; - } - }); - configWebEngine(); - webView.setContextMenuEnabled(false);//屏蔽右键 - root.setCenter(webView); - } - }); - } - - private void configWebEngine() { - - webEngine.locationProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, final String oldValue, String newValue) { - disableLink(webEngine); - // webView好像默认以手机版显示网页,浏览器里过滤掉这个跳转 - if (ComparatorUtils.equals(newValue, url) || ComparatorUtils.equals(newValue, CloudCenter.getInstance().acquireUrlByKind("bbs.mobile"))) { - return; - } - LoginWebBridge.getHelper().openUrlAtLocalWebBrowser(webEngine, newValue); - } - }); - - webEngine.setOnAlert(new EventHandler>() { - @Override - public void handle(WebEvent event) { - showAlert(event.getData()); - } - }); - - webEngine.getLoadWorker().stateProperty().addListener( - new ChangeListener() { - public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) { - if (newState == Worker.State.SUCCEEDED) { - window = (JSObject) webEngine.executeScript("window"); - window.setMember("QQLoginHelper", LoginWebBridge.getHelper()); - } - } - } - ); - } - - private void showAlert(final String message) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - FineJOptionPane.showMessageDialog(QQLoginWebPane.this, message); - } - }); - } - - private void disableLink(final WebEngine eng) { - try { - // webView端不跳转 虽然webView可以指定本地浏览器打开某个链接,但是当本地浏览器跳转到指定链接的同时,webView也做了跳转, - // 为了避免出现在一个600*400的资讯框里加载整个网页的情况,webView不跳转到新网页 - Platform.runLater(new Runnable() { - @Override - public void run() { - eng.executeScript("location.reload()"); - LoginWebBridge.getHelper().closeQQWindow(); - } - }); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - } - - private Boolean confirm(final Stage parent, String msg, final WebView webView) { - final BooleanProperty confirmationResult = new SimpleBooleanProperty(); - // initialize the confirmation dialog - final Stage dialog = new Stage(StageStyle.UTILITY); - dialog.setX(Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - DEFAULT_CONFIRM_WIDTH / 2.0D + DEFAULT_OFFEST); - dialog.setY(Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 + DEFAULT_OFFEST); - dialog.setHeight(DEFAULT_CONFIRM_HEIGHT); - dialog.setWidth(DEFAULT_CONFIRM_WIDTH); - dialog.setIconified(false); - dialog.initOwner(parent); - dialog.initModality(Modality.WINDOW_MODAL); - dialog.setScene( - new Scene( - HBoxBuilder.create().styleClass("modal-dialog").children( - LabelBuilder.create().text(msg).build(), - ButtonBuilder.create().text(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_BBSLogin_Switch_Account")).defaultButton(true).onAction(new EventHandler() { - @Override - public void handle(ActionEvent actionEvent) { - // take action and close the dialog. - confirmationResult.set(true); - webView.getEngine().reload(); - dialog.close(); - } - }).build(), - ButtonBuilder.create().text(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Engine_Cancel")).cancelButton(true).onAction(new EventHandler() { - @Override - public void handle(ActionEvent actionEvent) { - // abort action and close the dialog. - confirmationResult.set(false); - dialog.close(); - } - }).build() - ).build() - , Color.TRANSPARENT - ) - ); - configDrag(dialog); - // style and show the dialog. - dialog.getScene().getStylesheets().add(IOUtils.getResource("modal-dialog.css", getClass()).toExternalForm()); - dialog.setOnCloseRequest(new EventHandler() { - @Override - public void handle(WindowEvent event) { - event.consume(); - dialog.close(); - } - }); - dialog.showAndWait(); - return confirmationResult.get(); - } - - private void configDrag(final Stage dialog) { - // allow the dialog to be dragged around. - final Node root = dialog.getScene().getRoot(); - final Delta dragDelta = new Delta(); - - root.setOnMousePressed(new EventHandler() { - @Override - public void handle(MouseEvent mouseEvent) { - // record a delta distance for the drag and drop operation. - dragDelta.x = dialog.getX() - mouseEvent.getScreenX(); - dragDelta.y = dialog.getY() - mouseEvent.getScreenY(); - } - }); - root.setOnMouseDragged(new EventHandler() { - @Override - public void handle(MouseEvent mouseEvent) { - dialog.setX(mouseEvent.getScreenX() + dragDelta.x); - dialog.setY(mouseEvent.getScreenY() + dragDelta.y); - } - }); - } -} diff --git a/designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java b/designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java index 04b2db91ac..d7f858b65f 100644 --- a/designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java +++ b/designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java @@ -183,21 +183,6 @@ public class WebViewDlgHelper { } } - public static void createQQLoginDialog() { - try { - Class clazz = Class.forName("com.fr.design.extra.QQLoginWebPane"); - Constructor constructor = clazz.getConstructor(String.class); - Component webPane = (Component) constructor.newInstance(new File(installHome).getAbsolutePath()); - - UIDialog qqLoginDialog = new QQLoginDialog(DesignerContext.getDesignerFrame(), webPane); - LoginWebBridge.getHelper().setQQDialog(qqLoginDialog); - qqLoginDialog.setVisible(true); - } catch (Throwable ignored) { - // ignored - } - } - - private static void confirmDownLoadShopJS() { int rv = FineJOptionPane.showConfirmDialog( null, diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/UIBubbleFloatPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/UIBubbleFloatPane.java index c41cc9f7ac..0297353ee0 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/UIBubbleFloatPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/UIBubbleFloatPane.java @@ -2,9 +2,9 @@ package com.fr.design.gui.frpane; import com.fr.design.beans.BasicBeanPane; import com.fr.design.dialog.UIDialog; +import com.fr.design.utils.AWTUtilities; import com.fr.log.FineLoggerFactory; import com.fr.stable.Constants; -import com.sun.awt.AWTUtilities; import javax.swing.JComponent; import javax.swing.JPanel; diff --git a/designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java b/designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java index ec5da8bcaf..3eed2d799d 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UICheckListPopup.java @@ -36,14 +36,20 @@ public class UICheckListPopup extends UIPopupMenu { private UIScrollPane jScrollPane; private Color mouseEnteredColor = UIConstants.CHECKBOX_HOVER_SELECTED; private int maxDisplayNumber = 8; + private boolean supportSelectAll = true; public static final String COMMIT_EVENT = "commit"; - public static final String SELECT_ALL = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Choose_All"); + private static final String SELECT_ALL = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Choose_All"); private static final int CHECKBOX_HEIGHT = 25; - public UICheckListPopup(Object[] value) { + public UICheckListPopup(Object[] values) { + this(values, true); + } + + public UICheckListPopup(Object[] value, boolean supportSelectAll) { super(); values = value; + this.supportSelectAll = supportSelectAll; initComponent(); } @@ -78,7 +84,9 @@ public class UICheckListPopup extends UIPopupMenu { checkBoxList.clear(); //全选加在第一个位置 - addOneCheckValue(SELECT_ALL); + if (supportSelectAll) { + addOneCheckValue(SELECT_ALL); + } for (Object checkValue : values) { addOneCheckValue(checkValue); } @@ -151,7 +159,7 @@ public class UICheckListPopup extends UIPopupMenu { private void addSelectListener() { for (int i = 0; i < checkBoxList.size(); i++) { JCheckBox checkBox = checkBoxList.get(i); - if (i == 0) { + if (supportSelectAll && i == 0) { checkBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { @@ -189,7 +197,8 @@ public class UICheckListPopup extends UIPopupMenu { List allValue = Arrays.asList(values); for (Object value : selectedValues.keySet()) { int index = allValue.indexOf(value); - checkBoxList.get(index + 1).setSelected(selectedValues.get(value)); + index = supportSelectAll ? index + 1 : index; + checkBoxList.get(index).setSelected(selectedValues.get(value)); } } @@ -201,15 +210,19 @@ public class UICheckListPopup extends UIPopupMenu { public Object[] getSelectedValues() { List selectedValues = new ArrayList(); int selectCount = 0; - - for (int i = 1; i < checkBoxList.size(); i++) { + int startIndex = supportSelectAll ? 1 : 0; + for (int i = startIndex; i < checkBoxList.size(); i++) { if (checkBoxList.get(i).isSelected()) { - selectedValues.add(values[i - 1]); + int valueIndex = supportSelectAll ? i - 1 : i; + selectedValues.add(values[valueIndex]); selectCount++; } } + //全选半选切换 - switchSelectIcon(selectCount); + if (supportSelectAll) { + switchSelectIcon(selectCount); + } return selectedValues.toArray(new Object[selectedValues.size()]); } diff --git a/designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java b/designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java index d2479ae04b..4dcea229ce 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java @@ -59,8 +59,18 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam private String multiComboName = StringUtils.EMPTY; private boolean showOmitText = true; + private boolean supportSelectAll = true; + public UIComboCheckBox(Object[] value) { - this(value, DEFAULT_VALUE_SPERATOR); + this(value, DEFAULT_VALUE_SPERATOR, true); + } + + public UIComboCheckBox(Object[] value, boolean supportSelectAll) { + this(value, DEFAULT_VALUE_SPERATOR, supportSelectAll); + } + + public UIComboCheckBox(Object[] values, String valueSperator) { + this(values, valueSperator, true); } /** @@ -69,8 +79,9 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam * @param value * @param valueSperator */ - public UIComboCheckBox(Object[] value, String valueSperator) { + public UIComboCheckBox(Object[] value, String valueSperator, boolean supportSelectAll) { values = value; + this.supportSelectAll = supportSelectAll; this.valueSperator = valueSperator; initComponent(); } @@ -102,7 +113,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam private void initComponent() { this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); - this.popup = new UICheckListPopup(values); + this.popup = new UICheckListPopup(values, supportSelectAll); this.popup.addActionListener(new PopupAction()); this.editor = createEditor(); this.arrowButton = createArrowButton(); diff --git a/designer-base/src/main/java/com/fr/design/gui/ifilechooser/UINativeFileChooser.java b/designer-base/src/main/java/com/fr/design/gui/ifilechooser/UINativeFileChooser.java index 597f733f1e..c1418f834b 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ifilechooser/UINativeFileChooser.java +++ b/designer-base/src/main/java/com/fr/design/gui/ifilechooser/UINativeFileChooser.java @@ -1,5 +1,6 @@ package com.fr.design.gui.ifilechooser; +import com.fr.design.gui.ifilechooser.AbstractFileChooser; import com.fr.design.mainframe.DesignerContext; import com.fr.stable.os.OperatingSystem; diff --git a/designer-base/src/main/java/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextArea.java b/designer-base/src/main/java/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextArea.java index 30fc7b8717..9cdc3b0ef5 100644 --- a/designer-base/src/main/java/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextArea.java +++ b/designer-base/src/main/java/com/fr/design/gui/syntax/ui/rsyntaxtextarea/RSyntaxTextArea.java @@ -9,16 +9,7 @@ */ package com.fr.design.gui.syntax.ui.rsyntaxtextarea; -import java.awt.Color; -import java.awt.Cursor; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.RenderingHints; +import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -604,7 +595,7 @@ private boolean fractionalFontMetricsEnabled; SecurityManager sm = System.getSecurityManager(); if (sm!=null) { try { - sm.checkSystemClipboardAccess(); + sm.checkPermission(new AWTPermission("accessClipboard")); } catch (SecurityException se) { UIManager.getLookAndFeel().provideErrorFeedback(null); return; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index e52d4333fd..a31b77650e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java @@ -509,7 +509,8 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta if (OperatingSystem.isMacos()) { Class clazz = Class.forName("com.apple.eawt.Application"); BufferedImage icon = image.isEmpty() ? IOUtils.readImage("/com/fr/base/images/oem/logo.png") : image.get(image.size() - 1); - Reflect.on(Reflect.on(clazz).call("getApplication").get()).call("setDockIconImage", icon); + Object application = Reflect.on(clazz).call("getApplication").get(); + Reflect.on(application).call("setDockIconImage", icon); } else { this.setIconImages(image); } diff --git a/designer-base/src/main/java/com/fr/design/os/impl/MacOsAddListenerAction.java b/designer-base/src/main/java/com/fr/design/os/impl/MacOsAddListenerAction.java index 1ff796a1dc..d2ab576205 100644 --- a/designer-base/src/main/java/com/fr/design/os/impl/MacOsAddListenerAction.java +++ b/designer-base/src/main/java/com/fr/design/os/impl/MacOsAddListenerAction.java @@ -9,11 +9,16 @@ import com.fr.invoke.Reflect; import com.fr.log.FineLoggerFactory; import com.fr.stable.os.support.OSBasedAction; +import java.awt.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** + * com.apple.eawt.Application属于jdk1.8及以下mac jdk特有的api + * 在jdk9中被移除,由Desktop.getDesktop().setQuitHandler等jdk9.0引入的新api替代 + * 参见 https://stackoverflow.com/questions/38381824/how-can-i-use-apple-com-apple-eawt-functionality-on-java-8 + * * @author hades * @version 10.0 * Created by hades on 2020/3/13 @@ -28,10 +33,21 @@ public class MacOsAddListenerAction implements OSBasedAction { Object quitInstance = getProxy(quitHandler, "handleQuitRequestWith", new QuitAction()); Class aboutHandler = Class.forName("com.apple.eawt.AboutHandler"); Object aboutInstance = getProxy(aboutHandler, "handleAbout", new AboutAction()); - Reflect.on(Reflect.on(app).call("getApplication").get()).call("setQuitHandler", quitInstance) + Object application = Reflect.on(app).call("getApplication").get(); + Reflect.on(application).call("setQuitHandler", quitInstance) .call("setAboutHandler", aboutInstance); } catch (ClassNotFoundException e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + // 上面的不能移除,同时要保证再jdk1.8下面能运行 + // 抛出异常时 说明使用>=jdk9运行行设计器,但由于编译使用1.8构建,使用反射运行 + try { + Class quitHandler = Class.forName("java.awt.desktop.QuitHandler"); + Object quitInstance = getProxy(quitHandler, "handleQuitRequestWith", new QuitAction()); + Class aboutHandler = Class.forName("java.awt.desktop.AboutHandler"); + Object aboutInstance = getProxy(aboutHandler, "handleAbout", new AboutAction()); + Reflect.on(Desktop.getDesktop()).call("setQuitHandler", quitInstance).call("setAboutHandler", aboutInstance); + } catch (ClassNotFoundException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } } } diff --git a/designer-base/src/main/java/com/fr/design/ui/Assistant.java b/designer-base/src/main/java/com/fr/design/ui/Assistant.java deleted file mode 100644 index 3962692c73..0000000000 --- a/designer-base/src/main/java/com/fr/design/ui/Assistant.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.fr.design.ui; - -import com.fr.stable.StringUtils; -import com.teamdev.jxbrowser.chromium.Browser; -import com.teamdev.jxbrowser.chromium.BrowserContext; -import com.teamdev.jxbrowser.chromium.ProtocolService; -import com.teamdev.jxbrowser.chromium.URLResponse; - -import javax.activation.MimetypesFileTypeMap; -import java.io.DataInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * @author richie - * @version 10.0 - * Created by richie on 2019-03-07 - */ -public class Assistant { - - public static URLResponse inputStream2Response(InputStream inputStream, String filePath) throws Exception { - URLResponse response = new URLResponse(); - DataInputStream stream = new DataInputStream(inputStream); - byte[] data = new byte[stream.available()]; - stream.readFully(data); - response.setData(data); - String mimeType = getMimeType(filePath); - response.getHeaders().setHeader("Content-Type", mimeType); - return response; - } - - - private static String getMimeType(String path) { - if (StringUtils.isBlank(path)) { - return "text/html"; - } - if (path.endsWith(".html")) { - return "text/html"; - } - if (path.endsWith(".css")) { - return "text/css"; - } - if (path.endsWith(".js")) { - return "text/javascript"; - } - if (path.endsWith(".svg")) { - return "image/svg+xml"; - } - Path file = new File(path).toPath(); - try { - return Files.probeContentType(file); - } catch (IOException e) { - return "text/html"; - } - } - - public static void setEmbProtocolHandler(Browser browser, EmbProtocolHandler handler) { - BrowserContext browserContext = browser.getContext(); - ProtocolService protocolService = browserContext.getProtocolService(); - // 支持读取jar包中文件的自定义协议————emb:/com/fr/design/images/bbs.png - protocolService.setProtocolHandler("emb", handler); - protocolService.setProtocolHandler("file", handler); - } -} diff --git a/designer-base/src/main/java/com/fr/design/ui/EmbProtocolHandler.java b/designer-base/src/main/java/com/fr/design/ui/EmbProtocolHandler.java deleted file mode 100644 index 04d2f0f853..0000000000 --- a/designer-base/src/main/java/com/fr/design/ui/EmbProtocolHandler.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.fr.design.ui; - -import com.fr.base.TemplateUtils; -import com.fr.general.IOUtils; -import com.fr.log.FineLoggerFactory; -import com.fr.stable.EncodeConstants; -import com.fr.stable.StringUtils; -import com.fr.third.org.apache.commons.codec.net.URLCodec; -import com.fr.third.org.apache.commons.io.FileUtils; -import com.fr.third.org.apache.commons.io.FilenameUtils; -import com.fr.web.struct.AssembleComponent; -import com.fr.web.struct.AtomBuilder; -import com.fr.web.struct.PathGroup; -import com.fr.web.struct.category.ScriptPath; -import com.fr.web.struct.category.StylePath; -import com.teamdev.jxbrowser.chromium.ProtocolHandler; -import com.teamdev.jxbrowser.chromium.URLRequest; -import com.teamdev.jxbrowser.chromium.URLResponse; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.Map; - -/** - * @author richie - * @version 10.0 - * Created by richie on 2019-03-07 - */ -public class EmbProtocolHandler implements ProtocolHandler { - - private AssembleComponent component; - private Map map; - - public EmbProtocolHandler() { - - } - - public EmbProtocolHandler(AssembleComponent component) { - this.component = component; - } - - public EmbProtocolHandler(AssembleComponent component, Map map) { - this.component = component; - this.map = map; - } - - public EmbProtocolHandler(Map map) { - this.map = map; - } - - @Override - public URLResponse onRequest(URLRequest req) { - InputStream inputStream = null; - try { - String path = req.getURL(); - if (path.startsWith("file:")) { - String url = new URLCodec().decode(path); - String filePath = TemplateUtils.renderParameter4Tpl(url, map); - File file = new File(URI.create(filePath).getPath()); - inputStream = IOUtils.readResource(file.getAbsolutePath()); - String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8); - text = TemplateUtils.renderParameter4Tpl(text, map); - return Assistant.inputStream2Response(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), path); - } else if (path.startsWith("emb:dynamic")) { - URLResponse response = new URLResponse(); - response.setData(htmlText(map).getBytes()); - response.getHeaders().setHeader("Content-Type", "text/html"); - return response; - } else { - int index = path.indexOf("="); - if (index > 0) { - path = path.substring(index + 1); - } else { - path = path.substring(4); - } - inputStream = IOUtils.readResource(path); - return Assistant.inputStream2Response(inputStream, path); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().info(e.getMessage()); - } finally { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - } - } - return null; - } - - private String htmlText(Map map) { - PathGroup pathGroup = AtomBuilder.create().buildAssembleFilePath(ModernRequestClient.KEY, component); - StylePath[] stylePaths = pathGroup.toStylePathGroup(); - StringBuilder styleText = new StringBuilder(); - for (StylePath path : stylePaths) { - if (StringUtils.isNotBlank(path.toFilePath())) { - styleText.append(""); - } - } - String result = ModernUIConstants.HTML_TPL.replaceAll("##style##", styleText.toString()); - ScriptPath[] scriptPaths = pathGroup.toScriptPathGroup(); - StringBuilder scriptText = new StringBuilder(); - for (ScriptPath path : scriptPaths) { - if (StringUtils.isNotBlank(path.toFilePath())) { - scriptText.append(""); - } - } - result = result.replaceAll("##script##", scriptText.toString()); - if (map != null) { - for (Map.Entry entry : map.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - result = result.replaceAll("\\$\\{" + key + "}", value); - } - } - return result; - } -} diff --git a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java index 4a92d3715c..5b53e2ba82 100644 --- a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java +++ b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java @@ -7,21 +7,18 @@ import com.fr.design.gui.itoolbar.UIToolbar; import com.fr.design.i18n.Toolkit; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.web.struct.AssembleComponent; -import com.teamdev.jxbrowser.chromium.Browser; -import com.teamdev.jxbrowser.chromium.BrowserPreferences; -import com.teamdev.jxbrowser.chromium.JSValue; -import com.teamdev.jxbrowser.chromium.events.FinishLoadingEvent; -import com.teamdev.jxbrowser.chromium.events.LoadAdapter; -import com.teamdev.jxbrowser.chromium.events.LoadListener; -import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; -import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; -import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; -import com.teamdev.jxbrowser.chromium.swing.BrowserView; +import com.teamdev.jxbrowser.browser.Browser; +import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; +import com.teamdev.jxbrowser.engine.Engine; +import com.teamdev.jxbrowser.engine.EngineOptions; +import com.teamdev.jxbrowser.engine.RenderingMode; +import com.teamdev.jxbrowser.js.JsObject; +import com.teamdev.jxbrowser.net.Network; +import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback; +import com.teamdev.jxbrowser.view.swing.BrowserView; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.Map; /** @@ -42,9 +39,8 @@ public class ModernUIPane extends BasicPane { } private void initialize() { + setLayout(new BorderLayout()); if (browser == null) { - setLayout(new BorderLayout()); - BrowserPreferences.setChromiumSwitches("--disable-google-traffic"); if (DesignerEnvManager.getEnvManager().isOpenDebug()) { UIToolbar toolbar = new UIToolbar(); add(toolbar, BorderLayout.NORTH); @@ -55,75 +51,67 @@ public class ModernUIPane extends BasicPane { UIButton closeButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Close_Window")); toolbar.add(closeButton); - openDebugButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - showDebuggerDialog(); - } - }); + openDebugButton.addActionListener(e -> showDebuggerDialog()); - reloadButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - browser.reloadIgnoringCache(); - } - }); + reloadButton.addActionListener(e -> browser.navigation().reloadIgnoringCache()); - closeButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - SwingUtilities.getWindowAncestor(ModernUIPane.this).setVisible(false); - } - }); - BrowserPreferences.setChromiumSwitches("--remote-debugging-port=9222"); + closeButton.addActionListener(e -> SwingUtilities.getWindowAncestor(ModernUIPane.this).setVisible(false)); initializeBrowser(); - add(new BrowserView(browser), BorderLayout.CENTER); + add(BrowserView.newInstance(browser), BorderLayout.CENTER); } else { initializeBrowser(); - add(new BrowserView(browser), BorderLayout.CENTER); + add(BrowserView.newInstance(browser), BorderLayout.CENTER); } } } private void showDebuggerDialog() { JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this)); - Browser debugger = new Browser(); - BrowserView debuggerView = new BrowserView(debugger); + Engine engine = Engine.newInstance( + EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED) + .addSwitch("--disable-google-traffic") + .remoteDebuggingPort(9222).build()); + Browser debugger = engine.newBrowser(); + BrowserView debuggerView = BrowserView.newInstance(debugger); dialog.add(debuggerView, BorderLayout.CENTER); dialog.setSize(new Dimension(800, 400)); GUICoreUtils.centerWindow(dialog); dialog.setVisible(true); dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - debugger.loadURL(browser.getRemoteDebuggingURL()); + browser.devTools().remoteDebuggingUrl().ifPresent(url -> { + debugger.navigation().loadUrl(url); + }); } private void initializeBrowser() { - browser = new Browser(); + Engine engine = Engine.newInstance(EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").build()); + browser = engine.newBrowser(); // 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的 - browser.addScriptContextListener(new ScriptContextAdapter() { - @Override - public void onScriptContextCreated(ScriptContextEvent event) { - event.getBrowser().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace)); - } + browser.set(InjectJsCallback.class, params -> { + params.frame().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace)); + return InjectJsCallback.Response.proceed(); }); } /** * 转向一个新的地址,相当于重新加载 + * * @param url 新的地址 */ public void redirect(String url) { - browser.loadURL(url); + browser.navigation().loadUrl(url); } /** * 转向一个新的地址,相当于重新加载 + * * @param url 新的地址 * @param map 初始化参数 */ public void redirect(String url, Map map) { - Assistant.setEmbProtocolHandler(browser, new EmbProtocolHandler(map)); - browser.loadURL(url); + Network network = browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network, map)); + browser.navigation().loadUrl(url); } @Override @@ -133,19 +121,18 @@ public class ModernUIPane extends BasicPane { public void populate(final T t) { - browser.addScriptContextListener(new ScriptContextAdapter() { - @Override - public void onScriptContextCreated(ScriptContextEvent event) { - JSValue ns = event.getBrowser().executeJavaScriptAndReturnValue("window." + namespace); - ns.asObject().setProperty(variable, t); + browser.set(InjectJsCallback.class, params -> { + JsObject ns = params.frame().executeJavaScript("window." + namespace); + if (ns != null) { + ns.putProperty(variable, t); } + return InjectJsCallback.Response.proceed(); }); } public T update() { - JSValue jsValue = browser.executeJavaScriptAndReturnValue("window." + namespace + "." + expression); - if (jsValue.isObject()) { - return (T)jsValue.asJavaObject(); + if (browser.mainFrame().isPresent()) { + return browser.mainFrame().get().executeJavaScript("window." + namespace + "." + expression); } return null; } @@ -154,79 +141,89 @@ public class ModernUIPane extends BasicPane { private ModernUIPane pane = new ModernUIPane<>(); - public Builder prepare(ScriptContextListener contextListener) { - pane.browser.addScriptContextListener(contextListener); - return this; - } - - public Builder prepare(LoadListener loadListener) { - pane.browser.addLoadListener(loadListener); + public Builder prepare(InjectJsCallback callback) { + pane.browser.set(InjectJsCallback.class, callback); return this; } /** * 加载jar包中的资源 + * * @param path 资源路径 */ public Builder withEMB(final String path) { - Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); - pane.browser.loadURL("emb:" + path); + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network)); + pane.browser.navigation().loadUrl("emb:" + path); return this; } /** * 加载url指向的资源 + * * @param url 文件的地址 */ public Builder withURL(final String url) { - Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); - pane.browser.loadURL(url); + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network)); + pane.browser.navigation().loadUrl(url); return this; } /** * 加载url指向的资源 + * * @param url 文件的地址 */ public Builder withURL(final String url, Map map) { - Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(map)); - pane.browser.loadURL(url); + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network, map)); + pane.browser.navigation().loadUrl(url); return this; } /** * 加载Atom组件 + * * @param component Atom组件 */ public Builder withComponent(AssembleComponent component) { - Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component)); - pane.browser.loadURL("emb:dynamic"); + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, component)); + pane.browser.navigation().loadUrl("emb:dynamic"); return this; } /** * 加载Atom组件 + * * @param component Atom组件 */ public Builder withComponent(AssembleComponent component, Map map) { - Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler(component, map)); - pane.browser.loadURL("emb:dynamic"); + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, component, map)); + pane.browser.navigation().loadUrl("emb:dynamic"); return this; } /** * 加载html文本内容 + * * @param html 要加载html文本内容 */ public Builder withHTML(String html) { - Assistant.setEmbProtocolHandler(pane.browser, new EmbProtocolHandler()); - pane.browser.loadHTML(html); + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network)); + pane.browser.mainFrame().ifPresent(frame -> { + frame.loadHtml(html); + }); return this; } /** * 设置该前端页面做数据交换所使用的对象 + * * @param namespace 对象名 */ public Builder namespace(String namespace) { @@ -236,6 +233,7 @@ public class ModernUIPane extends BasicPane { /** * java端往js端传数据时使用的变量名字 + * * @param name 变量的名字 */ public Builder variable(String name) { @@ -245,6 +243,7 @@ public class ModernUIPane extends BasicPane { /** * js端往java端传数据时执行的函数表达式 + * * @param expression 函数表达式 */ public Builder expression(String expression) { diff --git a/designer-base/src/main/java/com/fr/design/ui/NxComplexInterceptRequestCallback.java b/designer-base/src/main/java/com/fr/design/ui/NxComplexInterceptRequestCallback.java new file mode 100644 index 0000000000..9e9705695d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/NxComplexInterceptRequestCallback.java @@ -0,0 +1,85 @@ +package com.fr.design.ui; + +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; +import com.fr.web.struct.AssembleComponent; +import com.fr.web.struct.AtomBuilder; +import com.fr.web.struct.PathGroup; +import com.fr.web.struct.category.ScriptPath; +import com.fr.web.struct.category.StylePath; +import com.teamdev.jxbrowser.net.Network; +import com.teamdev.jxbrowser.net.UrlRequest; +import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback; + +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2020/3/25 + */ +public class NxComplexInterceptRequestCallback extends NxInterceptRequestCallback { + + private AssembleComponent component; + + public NxComplexInterceptRequestCallback(Network network, AssembleComponent component) { + super(network); + this.component = component; + } + + public NxComplexInterceptRequestCallback(Network network, AssembleComponent component, Map map) { + super(network, map); + this.component = component; + } + + @Override + protected Response next(UrlRequest urlRequest, String path) { + if (path.startsWith("emb:dynamic")) { + String text = htmlText(map); + return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, "text/html", text.getBytes(StandardCharsets.UTF_8))); + } else { + int index = path.indexOf("="); + if (index > 0) { + path = path.substring(index + 1); + } else { + path = path.substring(4); + } + InputStream inputStream = IOUtils.readResource(path); + return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, getMimeType(path), IOUtils.inputStream2Bytes(inputStream))); + } + } + + private String htmlText(Map map) { + PathGroup pathGroup = AtomBuilder.create().buildAssembleFilePath(ModernRequestClient.KEY, component); + StylePath[] stylePaths = pathGroup.toStylePathGroup(); + StringBuilder styleText = new StringBuilder(); + for (StylePath path : stylePaths) { + if (StringUtils.isNotBlank(path.toFilePath())) { + styleText.append(""); + } + } + String result = ModernUIConstants.HTML_TPL.replaceAll("##style##", styleText.toString()); + ScriptPath[] scriptPaths = pathGroup.toScriptPathGroup(); + StringBuilder scriptText = new StringBuilder(); + for (ScriptPath path : scriptPaths) { + if (StringUtils.isNotBlank(path.toFilePath())) { + scriptText.append(""); + } + } + result = result.replaceAll("##script##", scriptText.toString()); + if (map != null) { + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + result = result.replaceAll("\\$\\{" + key + "}", value); + } + } + return result; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/ui/NxInterceptRequestCallback.java b/designer-base/src/main/java/com/fr/design/ui/NxInterceptRequestCallback.java new file mode 100644 index 0000000000..ea921efe04 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/NxInterceptRequestCallback.java @@ -0,0 +1,134 @@ +package com.fr.design.ui; + +import com.fr.base.TemplateUtils; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.EncodeConstants; +import com.fr.stable.StringUtils; +import com.fr.third.org.apache.commons.codec.net.URLCodec; +import com.teamdev.jxbrowser.net.HttpHeader; +import com.teamdev.jxbrowser.net.HttpStatus; +import com.teamdev.jxbrowser.net.Network; +import com.teamdev.jxbrowser.net.UrlRequest; +import com.teamdev.jxbrowser.net.UrlRequestJob; +import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2020/3/25 + */ +public class NxInterceptRequestCallback implements InterceptRequestCallback { + + Network network; + Map map; + + public NxInterceptRequestCallback(Network network) { + this.network = network; + } + + public NxInterceptRequestCallback(Network network, Map map) { + this.network = network; + this.map = map; + } + + @Override + public Response on(Params params) { + UrlRequest urlRequest = params.urlRequest(); + String path = urlRequest.url(); + if (path.startsWith("file:")) { + Optional optional = generateFileProtocolUrlRequestJob(urlRequest, path); + if (optional.isPresent()) { + return InterceptRequestCallback.Response.intercept(optional.get()); + } + } else { + return next(urlRequest, path); + } + return Response.proceed(); + } + + Response next(UrlRequest urlRequest, String path) { + return Response.proceed(); + } + + private Optional generateFileProtocolUrlRequestJob(UrlRequest urlRequest, String path) { + try { + String url = new URLCodec().decode(path); + String filePath = TemplateUtils.renderParameter4Tpl(url, map); + File file = new File(URI.create(filePath).getPath()); + InputStream inputStream = IOUtils.readResource(file.getAbsolutePath()); + String mimeType = getMimeType(path); + byte[] bytes; + if (isPlainText(mimeType)) { + String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8); + text = TemplateUtils.renderParameter4Tpl(text, map); + bytes = text.getBytes(StandardCharsets.UTF_8); + } else { + bytes = IOUtils.inputStream2Bytes(inputStream); + } + return Optional.of(generateBasicUrlRequestJob(urlRequest, mimeType, bytes)); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return Optional.empty(); + } + + private boolean isPlainText(String mimeType) { + return ArrayUtils.contains(new String[]{"text/html", "text/javascript", "text/css"}, mimeType); + } + + UrlRequestJob generateBasicUrlRequestJob(UrlRequest urlRequest, String mimeType, byte[] bytes) { + UrlRequestJob.Options options = UrlRequestJob.Options + .newBuilder(urlRequest.id(), HttpStatus.OK) + .addHttpHeader(HttpHeader.of("Content-Type", mimeType)) + .build(); + UrlRequestJob urlRequestJob = network.newUrlRequestJob(options); + urlRequestJob.write(bytes); + urlRequestJob.complete(); + return urlRequestJob; + } + + String getMimeType(String path) { + if (StringUtils.isBlank(path)) { + return "text/html"; + } + if (path.endsWith(".html")) { + return "text/html"; + } + if (path.endsWith(".css")) { + return "text/css"; + } + if (path.endsWith(".js")) { + return "text/javascript"; + } + if (path.endsWith(".svg")) { + return "image/svg+xml"; + } + if (path.endsWith(".png")) { + return "image/png"; + } + if (path.endsWith(".jpeg")) { + return "image/jpeg"; + } + if (path.endsWith(".gif")) { + return "image/gif"; + } + Path file = new File(path).toPath(); + try { + return Files.probeContentType(file); + } catch (IOException e) { + return "text/html"; + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/upm/UpmBridge.java b/designer-base/src/main/java/com/fr/design/upm/UpmBridge.java index e7d134808a..65b1c6b3b2 100644 --- a/designer-base/src/main/java/com/fr/design/upm/UpmBridge.java +++ b/designer-base/src/main/java/com/fr/design/upm/UpmBridge.java @@ -6,6 +6,7 @@ import com.fr.config.ServerPreferenceConfig; import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader; import com.fr.design.bridge.exec.JSBridge; import com.fr.design.bridge.exec.JSCallback; +import com.fr.design.bridge.exec.JSExecutor; import com.fr.design.extra.PluginOperateUtils; import com.fr.design.extra.PluginUtils; import com.fr.design.extra.exe.GetInstalledPluginsExecutor; @@ -28,10 +29,8 @@ import com.fr.log.FineLoggerFactory; import com.fr.plugin.context.PluginMarker; import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; -import com.teamdev.jxbrowser.chromium.Browser; -import com.teamdev.jxbrowser.chromium.JSArray; -import com.teamdev.jxbrowser.chromium.JSFunction; -import com.teamdev.jxbrowser.chromium.JSObject; +import com.teamdev.jxbrowser.js.JsAccessible; +import com.teamdev.jxbrowser.js.JsObject; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; @@ -52,42 +51,45 @@ import java.util.concurrent.RunnableFuture; */ public class UpmBridge { - public static UpmBridge getBridge(Browser browser) { - return new UpmBridge(browser); + public static UpmBridge getBridge() { + return new UpmBridge(); } - private JSObject window; - private UpmBridge(Browser browser) { - this.window = browser.executeJavaScriptAndReturnValue("window").asObject(); + private UpmBridge() { + } /** * 更新插件管理中心资源文件,这个方法仅仅是为了语义上的作用(更新) + * * @param callback 安装完成后的回调函数 */ @JSBridge - public void update(final JSFunction callback) { - callback.invoke(window, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start")); + @JsAccessible + public void update(final JsObject callback) { + callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start")); try { UpmResourceLoader.INSTANCE.download(); UpmResourceLoader.INSTANCE.install(); - callback.invoke(window, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success")); + callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success")); EventDispatcher.fire(DownloadEvent.UPDATE, "success"); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); - callback.invoke(window, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error")); + callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error")); } } /** * 下载并安装插件管理中心的资源文件 + * * @param callback 安装完成后的回调函数 */ @JSBridge - public void startDownload(final JSFunction callback) { - callback.invoke(window, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start")); - new SwingWorker(){ + @JsAccessible + public void startDownload(final JsObject callback) { + callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start")); + new SwingWorker() { @Override protected Void doInBackground() throws Exception { UpmResourceLoader.INSTANCE.download(); @@ -99,10 +101,10 @@ public class UpmBridge { protected void done() { try { get(); - callback.invoke(window, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success")); + callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success")); EventDispatcher.fire(DownloadEvent.SUCCESS, "success"); } catch (Exception e) { - callback.invoke(window, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error")); + callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error")); FineLoggerFactory.getLogger().error(e.getMessage(), e); EventDispatcher.fire(DownloadEvent.ERROR, "error"); } @@ -112,37 +114,44 @@ public class UpmBridge { /** * 获取upm的版本信息 + * * @return 版本信息 */ @JSBridge + @JsAccessible public String getVersion() { return ServerPreferenceConfig.getInstance().getOptimizedUPMVersion(); } @JSBridge + @JsAccessible public String i18nText(String key) { return Toolkit.i18nText(key); } @JSBridge + @JsAccessible public void closeWindow() { UpmFinder.closeWindow(); } @JSBridge + @JsAccessible public boolean isDesigner() { return true; } @JSBridge - public void getPackInfo(final JSFunction callback) { - callback.invoke(window, StringUtils.EMPTY); + @JsAccessible + public void getPackInfo(final JsObject callback) { + callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, StringUtils.EMPTY); } @JSBridge - public void getPluginPrefix(final JSFunction callback) { - UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginPrefixExecutor()); + @JsAccessible + public void getPluginPrefix(final JsObject callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new GetPluginPrefixExecutor()); task.execute(); } @@ -152,8 +161,9 @@ public class UpmBridge { * @param callback 回调函数 */ @JSBridge - public void getPluginCategories(final JSFunction callback) { - UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginCategoriesExecutor()); + @JsAccessible + public void getPluginCategories(final JsObject callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new GetPluginCategoriesExecutor()); task.execute(); } @@ -164,8 +174,9 @@ public class UpmBridge { * @param callback 回调函数 */ @JSBridge - public void getPluginFromStoreNew(String info, final JSFunction callback) { - UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetPluginFromStoreExecutor(new JSONObject(info))); + @JsAccessible + public void getPluginFromStoreNew(String info, final JsObject callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new GetPluginFromStoreExecutor(new JSONObject(info))); task.execute(); } @@ -173,8 +184,9 @@ public class UpmBridge { * 已安装插件检查更新 */ @JSBridge - public void readUpdateOnline(final JSFunction callback) { - UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new ReadUpdateOnlineExecutor()); + @JsAccessible + public void readUpdateOnline(final JsObject callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new ReadUpdateOnlineExecutor()); task.execute(); } @@ -182,8 +194,9 @@ public class UpmBridge { * 获取已经安装的插件的数组 */ @JSBridge - public void getInstalledPlugins(final JSFunction callback) { - UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new GetInstalledPluginsExecutor()); + @JsAccessible + public void getInstalledPlugins(final JsObject callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new GetInstalledPluginsExecutor()); task.execute(); } @@ -193,29 +206,36 @@ public class UpmBridge { * @param pluginIDs 插件集合 */ @JSBridge - public void updatePluginOnline(Object pluginIDs, final JSFunction callback) { - JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); + @JsAccessible + public void updatePluginOnline(JsObject pluginIDs, final JsObject callback) { + JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback)); List pluginMarkerList = new ArrayList<>(); - if (pluginIDs instanceof String) { - pluginMarkerList.add(PluginUtils.createPluginMarker(pluginIDs.toString())); - } else if (pluginIDs instanceof JSArray) { - JSArray pluginInfos = (JSArray) pluginIDs; - for (int i = 0, len = pluginInfos.length(); i < len; i++) { - String value = pluginInfos.get(i).asString().getValue(); - pluginMarkerList.add(PluginUtils.createPluginMarker(value)); - } + for (String key : pluginIDs.propertyNames()) { + pluginIDs.property(key).ifPresent(v -> { + pluginMarkerList.add(PluginUtils.createPluginMarker(GeneralUtils.objectToString(v))); + }); } PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback); } + @JSBridge + @JsAccessible + public void updatePluginOnline(String pluginID, final JsObject callback) { + JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback)); + List pluginMarkerList = new ArrayList<>(); + pluginMarkerList.add(PluginUtils.createPluginMarker(pluginID)); + PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback); + } + /** * 搜索在线插件 * * @param keyword 关键字 */ @JSBridge - public void searchPlugin(String keyword, final JSFunction callback) { - UpmTaskWorker worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new SearchOnlineExecutor(keyword)); + @JsAccessible + public void searchPlugin(String keyword, final JsObject callback) { + UpmTaskWorker worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new SearchOnlineExecutor(keyword)); worker.execute(); } @@ -225,8 +245,9 @@ public class UpmBridge { * @param filePath 插件包的路径 */ @JSBridge - public void installPluginFromDisk(final String filePath, final JSFunction callback) { - JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); + @JsAccessible + public void installPluginFromDisk(final String filePath, final JsObject callback) { + JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback)); File file = new File(filePath); PluginOperateUtils.installPluginFromDisk(file, jsCallback); } @@ -237,8 +258,9 @@ public class UpmBridge { * @param pluginInfo 插件信息 */ @JSBridge - public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JSFunction callback) { - JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); + @JsAccessible + public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JsObject callback) { + JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback)); PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback); } @@ -249,8 +271,9 @@ public class UpmBridge { * @param callback 回调函数 */ @JSBridge - public void installPluginOnline(final String pluginInfo, final JSFunction callback) { - JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); + @JsAccessible + public void installPluginOnline(final String pluginInfo, final JsObject callback) { + JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback)); PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo); PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback); } @@ -260,8 +283,10 @@ public class UpmBridge { * * @param filePath 插件包的路径 */ - public void updatePluginFromDisk(String filePath, final JSFunction callback) { - JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); + @JSBridge + @JsAccessible + public void updatePluginFromDisk(String filePath, final JsObject callback) { + JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback)); File file = new File(filePath); PluginOperateUtils.updatePluginFromDisk(file, jsCallback); } @@ -272,8 +297,9 @@ public class UpmBridge { * @param pluginID 插件ID */ @JSBridge - public void setPluginActive(String pluginID, final JSFunction callback) { - JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); + @JsAccessible + public void setPluginActive(String pluginID, final JsObject callback) { + JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback)); PluginOperateUtils.setPluginActive(pluginID, jsCallback); } @@ -283,6 +309,7 @@ public class UpmBridge { * @return 选择的文件的路径 */ @JSBridge + @JsAccessible public String showFileChooser() { return showFileChooserWithFilter(StringUtils.EMPTY, StringUtils.EMPTY); } @@ -296,6 +323,7 @@ public class UpmBridge { * 这里换用JFileChooser会卡死,不知道为什么 */ @JSBridge + @JsAccessible public String showFileChooserWithFilter(final String des, final String filter) { RunnableFuture future = new FutureTask<>(new Callable() { @Override @@ -318,7 +346,7 @@ public class UpmBridge { try { return future.get(); } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineLoggerFactory.getLogger().error(e.getMessage(), e); } return null; } @@ -331,31 +359,60 @@ public class UpmBridge { * @return 选择的文件的路径 */ @JSBridge - public String showFileChooserWithFilters(final String des, final Object args) { - RunnableFuture future = new FutureTask<>(new Callable() { - @Override - public String call() { - JFileChooser fileChooser = new JFileChooser(); - List filterList = new ArrayList<>(); - if (args instanceof String) { - filterList.add(GeneralUtils.objectToString(args)); - } else if (args instanceof JSArray) { - JSArray array = (JSArray)args; - for (int i = 0, len = array.length(); i < len; i ++) { - filterList.add(array.get(i).getStringValue()); - } - } - String[] filters = filterList.toArray(new String[0]); - if (ArrayUtils.isNotEmpty(filters)) { - FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters)); - fileChooser.setFileFilter(filter); - } - int result = fileChooser.showOpenDialog(UpmFinder.getDialog()); - if (result == JFileChooser.APPROVE_OPTION) { - return fileChooser.getSelectedFile().getAbsolutePath(); - } - return null; + @JsAccessible + public String showFileChooserWithFilters(final String des, final String args) { + RunnableFuture future = new FutureTask<>(() -> { + JFileChooser fileChooser = new JFileChooser(); + List filterList = new ArrayList<>(); + filterList.add(args); + String[] filters = filterList.toArray(new String[0]); + if (ArrayUtils.isNotEmpty(filters)) { + FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters)); + fileChooser.setFileFilter(filter); } + int result = fileChooser.showOpenDialog(UpmFinder.getDialog()); + if (result == JFileChooser.APPROVE_OPTION) { + return fileChooser.getSelectedFile().getAbsolutePath(); + } + return null; + }); + SwingUtilities.invokeLater(future); + try { + return future.get(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return null; + } + + /** + * 选择文件对话框 + * + * @param des 过滤文件描述 + * @param args 文件的后缀 + * @return 选择的文件的路径 + */ + @JSBridge + @JsAccessible + public String showFileChooserWithFilters(final String des, final JsObject args) { + RunnableFuture future = new FutureTask<>(() -> { + JFileChooser fileChooser = new JFileChooser(); + List filterList = new ArrayList<>(); + for (String key : args.propertyNames()) { + args.property(key).ifPresent(v -> { + filterList.add(GeneralUtils.objectToString(v)); + }); + } + String[] filters = filterList.toArray(new String[0]); + if (ArrayUtils.isNotEmpty(filters)) { + FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters)); + fileChooser.setFileFilter(filter); + } + int result = fileChooser.showOpenDialog(UpmFinder.getDialog()); + if (result == JFileChooser.APPROVE_OPTION) { + return fileChooser.getSelectedFile().getAbsolutePath(); + } + return null; }); SwingUtilities.invokeLater(future); try { @@ -372,7 +429,8 @@ public class UpmBridge { * 获取系统登录的用户名 */ @JSBridge - public String getLoginInfo(final JSFunction callback) { + @JsAccessible + public String getLoginInfo(final JsObject callback) { registerLoginInfo(callback); return MarketConfig.getInstance().getBbsUsername(); } @@ -383,8 +441,9 @@ public class UpmBridge { * @param callback 回调函数 */ @JSBridge - public void registerLoginInfo(final JSFunction callback) { - JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback)); + @JsAccessible + public void registerLoginInfo(final JsObject callback) { + JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(callback)); String username = MarketConfig.getInstance().getBbsUsername(); if (StringUtils.isEmpty(username)) { jsCallback.execute(StringUtils.EMPTY); @@ -404,14 +463,16 @@ public class UpmBridge { * @param callback 回调函数 */ @JSBridge - public void defaultLogin(String username, String password, final JSFunction callback) { - UpmTaskWorker worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(window, callback)), new PluginLoginExecutor(username, password)); + @JsAccessible + public void defaultLogin(String username, String password, final JsObject callback) { + UpmTaskWorker worker = new UpmTaskWorker<>(new JSCallback(UpmBrowserExecutor.create(callback)), new PluginLoginExecutor(username, password)); worker.execute(); } /** * 清除用户信息 */ + @JsAccessible public void clearUserInfo() { MarketConfig.getInstance().setInShowBBsName(StringUtils.EMPTY); FinePassportManager.getInstance().logout(); @@ -422,6 +483,7 @@ public class UpmBridge { * 打开论坛消息界面 */ @JSBridge + @JsAccessible public void getPriviteMessage() { try { String loginUrl = CloudCenter.getInstance().acquireUrlByKind("bbs.default"); @@ -435,6 +497,7 @@ public class UpmBridge { * 忘记密码 */ @JSBridge + @JsAccessible public void forgetHref() { try { Desktop.getDesktop().browse(new URI(CloudCenter.getInstance().acquireUrlByKind("bbs.reset"))); @@ -447,6 +510,7 @@ public class UpmBridge { * 立即注册 */ @JSBridge + @JsAccessible public void registerHref() { try { Desktop.getDesktop().browse(new URI(CloudCenter.getInstance().acquireUrlByKind("bbs.register"))); @@ -457,9 +521,11 @@ public class UpmBridge { /** * 使用系统浏览器打开网页 + * * @param url 要打开的网页 */ @JSBridge + @JsAccessible public void openShopUrlAtWebBrowser(String url) { if (Desktop.isDesktopSupported()) { try { diff --git a/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java b/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java index 9a6205cf4a..ea55c7537c 100644 --- a/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java +++ b/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java @@ -58,7 +58,7 @@ public class UpmFinder { public static void showUPMDialog() { boolean flag = true; try { - Class.forName("com.teamdev.jxbrowser.chromium.Browser"); + Class.forName("com.teamdev.jxbrowser.browser.Browser"); } catch (ClassNotFoundException e) { flag = false; } diff --git a/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java b/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java index 1bc4b9e948..f4019cf060 100644 --- a/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java +++ b/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java @@ -6,9 +6,8 @@ import com.fr.design.upm.event.DownloadEvent; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; -import com.teamdev.jxbrowser.chromium.JSValue; -import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; -import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; +import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; +import com.teamdev.jxbrowser.js.JsObject; import java.awt.*; @@ -32,12 +31,10 @@ public class UpmShowPane extends BasicPane { // 先屏蔽掉这个判断,后续可能修改交互 // if (UpmFinder.checkUPMResourcesExist()) { modernUIPane = new ModernUIPane.Builder<>() - .prepare(new ScriptContextAdapter() { - @Override - public void onScriptContextCreated(ScriptContextEvent event) { - JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window"); - window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser())); - } + .prepare(params -> { + JsObject window = params.frame().executeJavaScript("window"); + window.putProperty("PluginHelper", UpmBridge.getBridge()); + return InjectJsCallback.Response.proceed(); }) .withURL(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()) .build(); diff --git a/designer-base/src/main/java/com/fr/design/upm/exec/UpmBrowserExecutor.java b/designer-base/src/main/java/com/fr/design/upm/exec/UpmBrowserExecutor.java index 572f7b5f23..f2f10ffdfb 100644 --- a/designer-base/src/main/java/com/fr/design/upm/exec/UpmBrowserExecutor.java +++ b/designer-base/src/main/java/com/fr/design/upm/exec/UpmBrowserExecutor.java @@ -1,8 +1,7 @@ package com.fr.design.upm.exec; import com.fr.design.bridge.exec.JSExecutor; -import com.teamdev.jxbrowser.chromium.JSFunction; -import com.teamdev.jxbrowser.chromium.JSObject; +import com.teamdev.jxbrowser.js.JsObject; /** * @author richie @@ -11,20 +10,18 @@ import com.teamdev.jxbrowser.chromium.JSObject; */ public class UpmBrowserExecutor implements JSExecutor { - public static UpmBrowserExecutor create(JSObject window, JSFunction callback) { - return new UpmBrowserExecutor(window, callback); + public static UpmBrowserExecutor create(JsObject callback) { + return new UpmBrowserExecutor(callback); } - private JSObject window; - private JSFunction callback; + private JsObject callback; - private UpmBrowserExecutor(JSObject window, JSFunction callback) { - this.window = window; + private UpmBrowserExecutor(JsObject callback) { this.callback = callback; } @Override public void executor(String newValue) { - callback.invoke(window, newValue); + callback.call(JSExecutor.CALLBACK_FUNCTION_NAME, newValue); } } diff --git a/designer-base/src/main/java/com/fr/design/utils/AWTUtilities.java b/designer-base/src/main/java/com/fr/design/utils/AWTUtilities.java new file mode 100644 index 0000000000..12bf2ac4d6 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/utils/AWTUtilities.java @@ -0,0 +1,200 @@ +package com.fr.design.utils; + +import sun.awt.SunToolkit; + +import java.awt.*; + +/** + * 适配jdk10之后被移除的 com.sun.awt.AWTUtilities + * 参照 https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/com/sun/awt/AWTUtilities.java中实现 + * + * @author hades + * @version 10.0 + * Created by hades on 2020/5/29 + */ +public class AWTUtilities { + + /** + * @param window the window to set the shape to + * @param shape the shape to set to the window + * + */ + public static void setWindowShape(Window window, Shape shape) { + if (window == null) { + throw new NullPointerException("The window argument should not be null."); + } + window.setShape(shape); + } + + /** + * + * + * @param window the window to set the shape to + * @param opaque whether the window must be opaque (true), + * or translucent (false) + * + */ + public static void setWindowOpaque(Window window, boolean opaque) { + if (window == null) { + throw new NullPointerException("The window argument should not be null."); + } + if (!opaque && !isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) { + throw new UnsupportedOperationException("The PERPIXEL_TRANSLUCENT translucency kind is not supported"); + } + Color color = window.getBackground(); + if (color == null) { + color = new Color(0, 0, 0, 0); + } + window.setBackground(new Color(color.getRed(), color.getGreen(), color.getBlue(), opaque ? 255 : 0)); + } + + + public static enum Translucency { + /** + * Represents support in the underlying system for windows each pixel + * of which is guaranteed to be either completely opaque, with + * an alpha value of 1.0, or completely transparent, with an alpha + * value of 0.0. + */ + PERPIXEL_TRANSPARENT, + + /** + * Represents support in the underlying system for windows all of + * the pixels of which have the same alpha value between or including + * 0.0 and 1.0. + */ + TRANSLUCENT, + + /** + * Represents support in the underlying system for windows that + * contain or might contain pixels with arbitrary alpha values + * between and including 0.0 and 1.0. + */ + PERPIXEL_TRANSLUCENT; + } + + + /** + * Returns whether the given level of translucency is supported by + * the underlying system. + * + * Note that this method may sometimes return the value + * indicating that the particular level is supported, but + * the native windowing system may still not support the + * given level of translucency (due to the bugs in + * the windowing system). + * + * @param translucencyKind a kind of translucency support + * (either PERPIXEL_TRANSPARENT, + * TRANSLUCENT, or PERPIXEL_TRANSLUCENT) + * @return whether the given translucency kind is supported + */ + private static boolean isTranslucencySupported(Translucency translucencyKind) { + switch (translucencyKind) { + case PERPIXEL_TRANSPARENT: + return isWindowShapingSupported(); + case TRANSLUCENT: + return isWindowOpacitySupported(); + case PERPIXEL_TRANSLUCENT: + return isWindowTranslucencySupported(); + } + return false; + } + + /** + * Returns whether the windowing system supports changing the opacity + * value of top-level windows. + * Note that this method may sometimes return true, but the native + * windowing system may still not support the concept of + * translucency (due to the bugs in the windowing system). + */ + private static boolean isWindowOpacitySupported() { + Toolkit curToolkit = Toolkit.getDefaultToolkit(); + if (!(curToolkit instanceof SunToolkit)) { + return false; + } + return ((SunToolkit)curToolkit).isWindowOpacitySupported(); + } + + /** + * Returns whether the windowing system supports changing the shape + * of top-level windows. + * Note that this method may sometimes return true, but the native + * windowing system may still not support the concept of + * shaping (due to the bugs in the windowing system). + */ + private static boolean isWindowShapingSupported() { + Toolkit curToolkit = Toolkit.getDefaultToolkit(); + if (!(curToolkit instanceof SunToolkit)) { + return false; + } + return ((SunToolkit)curToolkit).isWindowShapingSupported(); + } + + private static boolean isWindowTranslucencySupported() { + /* + * Per-pixel alpha is supported if all the conditions are TRUE: + * 1. The toolkit is a sort of SunToolkit + * 2. The toolkit supports translucency in general + * (isWindowTranslucencySupported()) + * 3. There's at least one translucency-capable + * GraphicsConfiguration + */ + + Toolkit curToolkit = Toolkit.getDefaultToolkit(); + if (!(curToolkit instanceof SunToolkit)) { + return false; + } + + if (!((SunToolkit)curToolkit).isWindowTranslucencySupported()) { + return false; + } + + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + + // If the default GC supports translucency return true. + // It is important to optimize the verification this way, + // see CR 6661196 for more details. + if (isTranslucencyCapable(env.getDefaultScreenDevice() + .getDefaultConfiguration())) + { + return true; + } + + // ... otherwise iterate through all the GCs. + GraphicsDevice[] devices = env.getScreenDevices(); + + for (int i = 0; i < devices.length; i++) { + GraphicsConfiguration[] configs = devices[i].getConfigurations(); + for (int j = 0; j < configs.length; j++) { + if (isTranslucencyCapable(configs[j])) { + return true; + } + } + } + + return false; + } + + private static boolean isTranslucencyCapable(GraphicsConfiguration gc) { + if (gc == null) { + throw new NullPointerException("The gc argument should not be null"); + } + /* + return gc.isTranslucencyCapable(); + */ + Toolkit curToolkit = Toolkit.getDefaultToolkit(); + if (!(curToolkit instanceof SunToolkit)) { + return false; + } + return ((SunToolkit)curToolkit).isTranslucencyCapable(gc); + } + + + + + + + +} diff --git a/designer-base/src/main/java/com/fr/start/SplashWindow.java b/designer-base/src/main/java/com/fr/start/SplashWindow.java index 0176883f57..b6a012f95a 100644 --- a/designer-base/src/main/java/com/fr/start/SplashWindow.java +++ b/designer-base/src/main/java/com/fr/start/SplashWindow.java @@ -2,9 +2,9 @@ package com.fr.start; import com.fr.base.BaseUtils; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.utils.AWTUtilities; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.stable.OperatingSystem; -import com.sun.awt.AWTUtilities; import javax.swing.ImageIcon; import javax.swing.JFrame; @@ -41,7 +41,6 @@ public class SplashWindow extends JFrame { this.setAlwaysOnTop(false); this.setUndecorated(true); AWTUtilities.setWindowOpaque(this, false); - //使窗体背景透明 if (OperatingSystem.isWindows()) { this.setBackground(new Color(0, 0, 0, 0)); diff --git a/designer-base/src/test/java/com/fr/design/gui/icombocheckbox/UICheckListPopupTest.java b/designer-base/src/test/java/com/fr/design/gui/icombocheckbox/UICheckListPopupTest.java new file mode 100644 index 0000000000..33a98e078d --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/gui/icombocheckbox/UICheckListPopupTest.java @@ -0,0 +1,41 @@ +package com.fr.design.gui.icombocheckbox; + +import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2020/4/3 + */ +public class UICheckListPopupTest extends TestCase { + + @Test + public void testGetSelectedValues() { + Object[] values = new Object[]{"a", "b", "c"}; + Map map = new TreeMap<>(); + map.put("a", true); + map.put("b", false); + map.put("c", true); + List list = new ArrayList<>(); + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue()) { + list.add(entry.getKey()); + } + } + Object[] selectValues = list.toArray(); + UICheckListPopup uiCheckListPopup1 = new UICheckListPopup(values); + uiCheckListPopup1.setSelectedValue(map); + Assert.assertArrayEquals(selectValues, uiCheckListPopup1.getSelectedValues()); + UICheckListPopup uiCheckListPopup2 = new UICheckListPopup(values, false); + uiCheckListPopup2.setSelectedValue(map); + Assert.assertArrayEquals(selectValues, uiCheckListPopup2.getSelectedValues()); + } + +} \ No newline at end of file diff --git a/designer-chart/build.gradle b/designer-chart/build.gradle new file mode 100644 index 0000000000..e59f9ef2f8 --- /dev/null +++ b/designer-chart/build.gradle @@ -0,0 +1,3 @@ +dependencies { + compile project(':designer-base') +} diff --git a/designer-form/build.gradle b/designer-form/build.gradle new file mode 100644 index 0000000000..e59f9ef2f8 --- /dev/null +++ b/designer-form/build.gradle @@ -0,0 +1,3 @@ +dependencies { + compile project(':designer-base') +} diff --git a/designer-realize/build.gradle b/designer-realize/build.gradle new file mode 100644 index 0000000000..ffb6823e88 --- /dev/null +++ b/designer-realize/build.gradle @@ -0,0 +1,4 @@ +dependencies { + compile project(':designer-form') + compile project(':designer-chart') +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/listener/ComponentHandler.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/listener/ComponentHandler.java index 1294fd7d08..17f12f9dde 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/listener/ComponentHandler.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/listener/ComponentHandler.java @@ -1,6 +1,6 @@ package com.fr.design.mainframe.alphafine.listener; -import com.sun.awt.AWTUtilities; +import com.fr.design.utils.AWTUtilities; import java.awt.*; import java.awt.event.ComponentAdapter; diff --git a/globalConfigHook.gradle b/globalConfigHook.gradle new file mode 100644 index 0000000000..c625d05b1d --- /dev/null +++ b/globalConfigHook.gradle @@ -0,0 +1,29 @@ +def getRootGradle() { + def currentGradle = gradle + while (currentGradle.parent) { + currentGradle = currentGradle.parent + } + return currentGradle +} + +def findHookIncludedBuild() { + def rootGradle = getRootGradle() + def hookProject = rootGradle.getIncludedBuilds() + .find({ build -> build.name == 'hook' }) + return hookProject +} + +def findGlobalConfig() { + def hookProject = findHookIncludedBuild() + if (hookProject) { + def path = hookProject.projectDir.parent + '/globalConfig.gradle' + if (file(path).exists()) { + return path + } + } +} + +def globalConfigPath = findGlobalConfig() +if (globalConfigPath) { + apply from: globalConfigPath +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..f3d88b1c2f Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..e0c5e220cc --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Apr 22 15:17:12 CST 2020 +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100644 index 0000000000..af6708ff22 --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..6d57edc706 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml index 407f1fd17b..711751c9fb 100644 --- a/pom.xml +++ b/pom.xml @@ -28,8 +28,8 @@ maven-compiler-plugin 3.1 - 1.7 - 1.7 + 1.8 + 1.8 diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000000..077d17597b --- /dev/null +++ b/settings.gradle @@ -0,0 +1,12 @@ +pluginManagement { + repositories { + maven { + url 'http://mvn.finedevelop.com/repository/maven-public/' + } + gradlePluginPortal() + } +} + +rootProject.name = 'design' + +include 'designer-base', 'designer-chart', 'designer-form', 'designer-realize'