forked from fanruan/design
xiqiu
3 years ago
30 changed files with 1840 additions and 42 deletions
@ -0,0 +1,37 @@
|
||||
package com.fr.design.mainframe.share.mini; |
||||
|
||||
import com.fr.design.dialog.FineJOptionPane; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
|
||||
import javax.swing.JOptionPane; |
||||
import java.awt.Component; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/8 |
||||
*/ |
||||
public class MiniShopDisposingChecker { |
||||
|
||||
public static boolean check() { |
||||
return check(DesignerContext.getDesignerFrame()); |
||||
} |
||||
|
||||
public static boolean check(Component optionParentComponent) { |
||||
if (MiniShopNativeTaskManager.getInstance().hasExecutingTasks()) { |
||||
int result = FineJOptionPane.showConfirmDialog( |
||||
optionParentComponent, |
||||
Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Close_Tip"), |
||||
"", |
||||
FineJOptionPane.YES_NO_OPTION |
||||
); |
||||
if (result == JOptionPane.YES_OPTION) { |
||||
MiniShopNativeTaskManager.getInstance().cancelAllExecutingTasks(); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,11 @@
|
||||
package com.fr.design.mainframe.share.mini; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/8 |
||||
*/ |
||||
public interface MiniShopNativeTask { |
||||
void execute(); |
||||
void cancel(); |
||||
} |
@ -0,0 +1,42 @@
|
||||
package com.fr.design.mainframe.share.mini; |
||||
|
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/8 |
||||
*/ |
||||
public class MiniShopNativeTaskManager { |
||||
private MiniShopNativeTaskManager() { |
||||
} |
||||
private static class HOLDER { |
||||
private static final MiniShopNativeTaskManager singleton = new MiniShopNativeTaskManager(); |
||||
} |
||||
public static MiniShopNativeTaskManager getInstance() { |
||||
return MiniShopNativeTaskManager.HOLDER.singleton; |
||||
} |
||||
|
||||
|
||||
private static final Set<MiniShopNativeTask> executingTasks = new HashSet<>(); |
||||
|
||||
public void addStartedTask(MiniShopNativeTask task) { |
||||
executingTasks.add(task); |
||||
} |
||||
|
||||
public void removeCompletedTask(MiniShopNativeTask task) { |
||||
executingTasks.remove(task); |
||||
} |
||||
|
||||
public boolean hasExecutingTasks() { |
||||
return !executingTasks.isEmpty(); |
||||
} |
||||
|
||||
public void cancelAllExecutingTasks() { |
||||
for (MiniShopNativeTask executingTask: executingTasks) { |
||||
executingTask.cancel(); |
||||
} |
||||
executingTasks.clear(); |
||||
} |
||||
} |
@ -0,0 +1,33 @@
|
||||
package com.fr.design.startup; |
||||
|
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/11 |
||||
*/ |
||||
public class FineStartupNotificationFactory { |
||||
private static final FineStartupNotificationProvider DEFAULT = Install4jStartupNotificationProvider.getInstance(); |
||||
private static FineStartupNotificationProvider provider; |
||||
|
||||
public FineStartupNotificationFactory() { |
||||
} |
||||
|
||||
public static FineStartupNotificationProvider getNotification() { |
||||
return provider; |
||||
} |
||||
|
||||
public static void setLogger(@NotNull FineStartupNotificationProvider provider) { |
||||
FineStartupNotificationFactory.provider = provider; |
||||
} |
||||
|
||||
public static void reset() { |
||||
provider = DEFAULT; |
||||
} |
||||
|
||||
|
||||
static { |
||||
provider = DEFAULT; |
||||
} |
||||
} |
@ -0,0 +1,14 @@
|
||||
package com.fr.design.startup; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/11 |
||||
*/ |
||||
public interface FineStartupNotificationProvider { |
||||
void registerStartupListener(Listener listener); |
||||
|
||||
interface Listener { |
||||
void startupPerformed(String parameters); |
||||
} |
||||
} |
@ -0,0 +1,35 @@
|
||||
package com.fr.design.startup; |
||||
|
||||
import com.install4j.api.launcher.StartupNotification; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/11 |
||||
*/ |
||||
public class Install4jStartupNotificationProvider implements FineStartupNotificationProvider { |
||||
|
||||
private Install4jStartupNotificationProvider() { |
||||
} |
||||
private static final Install4jStartupNotificationProvider INSTANCE = new Install4jStartupNotificationProvider(); |
||||
public static Install4jStartupNotificationProvider getInstance() { |
||||
return INSTANCE; |
||||
} |
||||
|
||||
@Override |
||||
public void registerStartupListener(Listener listener) { |
||||
boolean supported = false; |
||||
try { |
||||
supported = Class.forName("com.install4j.api.launcher.StartupNotification") != null; |
||||
} catch (Throwable ignored) {} |
||||
|
||||
if (supported) { |
||||
StartupNotification.registerStartupListener(new StartupNotification.Listener() { |
||||
@Override |
||||
public void startupPerformed(String parameters) { |
||||
listener.startupPerformed(parameters); |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,38 @@
|
||||
package com.fr.design.mainframe.share.ui.online.installation; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/5 |
||||
*/ |
||||
public abstract class AsyncInstallation implements Installation { |
||||
private AsyncActionListener actionListener; |
||||
|
||||
public void setActionListener(AsyncActionListener actionListener) { |
||||
this.actionListener = actionListener; |
||||
} |
||||
|
||||
protected void notifyProgress(double value) { |
||||
if (this.actionListener != null) { |
||||
this.actionListener.onProgress(value); |
||||
} |
||||
} |
||||
protected void notifySuccess() { |
||||
if (this.actionListener != null) { |
||||
this.actionListener.onSuccess(); |
||||
} |
||||
} |
||||
protected void notifyFailed() { |
||||
if (this.actionListener != null) { |
||||
this.actionListener.onFailed(); |
||||
} |
||||
} |
||||
|
||||
public abstract void cancel(); |
||||
|
||||
public interface AsyncActionListener { |
||||
void onProgress(double value); |
||||
void onSuccess(); |
||||
void onFailed(); |
||||
} |
||||
} |
@ -0,0 +1,147 @@
|
||||
package com.fr.design.mainframe.share.ui.online.installation; |
||||
|
||||
import com.fr.design.DesignerEnvManager; |
||||
import com.fr.design.extra.Process; |
||||
import com.fr.design.login.DesignerLoginHelper; |
||||
import com.fr.design.login.DesignerLoginSource; |
||||
import com.fr.design.mainframe.share.collect.ComponentCollector; |
||||
import com.fr.design.mainframe.share.util.DownloadUtils; |
||||
import com.fr.design.mainframe.share.util.ShareComponentUtils; |
||||
import com.fr.form.share.Group; |
||||
import com.fr.form.share.bean.OnlineShareWidget; |
||||
import com.fr.form.share.group.DefaultShareGroup; |
||||
import com.fr.form.share.group.DefaultShareGroupManager; |
||||
import com.fr.form.share.utils.ShareUtils; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.StringUtils; |
||||
|
||||
import javax.swing.SwingWorker; |
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.concurrent.ExecutionException; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/5 |
||||
*/ |
||||
public class ComponentInstallation extends AsyncInstallation { |
||||
private final OnlineShareWidget widget; |
||||
private SwingWorker<Boolean, Void> worker; |
||||
|
||||
public ComponentInstallation(OnlineShareWidget widget) { |
||||
this.widget = widget; |
||||
} |
||||
|
||||
@Override |
||||
public void install() { |
||||
if (!checkLoginStatus()) { |
||||
notifyFailed(); |
||||
return; |
||||
} |
||||
notifyProgress(0.0D); |
||||
worker = createWorker(); |
||||
worker.execute(); |
||||
} |
||||
|
||||
private SwingWorker<Boolean, Void> createWorker() { |
||||
return new SwingWorker<Boolean, Void>() { |
||||
|
||||
@Override |
||||
protected Boolean doInBackground() { |
||||
|
||||
String tempFilePath = fetchRemoteReuFile2TempDir(); |
||||
if (StringUtils.isEmpty(tempFilePath)) { |
||||
return false; |
||||
} |
||||
if (isCancelled()) { |
||||
return false; |
||||
} |
||||
ShareComponentUtils.checkReadMe(); |
||||
if (isCancelled()) { |
||||
return false; |
||||
} |
||||
installTempReuFile(tempFilePath); |
||||
StableUtils.deleteFile(new File(tempFilePath)); |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
protected void done() { |
||||
boolean result = false; |
||||
try { |
||||
result = get(); |
||||
} catch (InterruptedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
Thread.currentThread().interrupt(); |
||||
} catch (ExecutionException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
|
||||
notifyProgress(0.0D); |
||||
if (result) { |
||||
notifySuccess(); |
||||
} else { |
||||
notifyFailed(); |
||||
} |
||||
} |
||||
}; |
||||
} |
||||
|
||||
private boolean checkLoginStatus() { |
||||
String userName = DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); |
||||
if (StringUtils.isEmpty(userName)) { |
||||
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL); |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
private String createLocalReuFilename() { |
||||
String filename = widget.getFileLoca(); |
||||
if (StringUtils.isEmpty(filename) || !filename.endsWith(".reu")) { |
||||
filename = widget.getName() + "." + widget.getUuid() + ".reu"; |
||||
} |
||||
return filename; |
||||
} |
||||
|
||||
private String fetchRemoteReuFile2TempDir() { |
||||
try { |
||||
String filename = createLocalReuFilename(); |
||||
return DownloadUtils.download(widget.getId(), filename, new Process<Double>() { |
||||
@Override |
||||
public void process(Double value) { |
||||
notifyProgress(value); |
||||
} |
||||
}); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
private void installTempReuFile(String tempFilePath) { |
||||
File file = new File(tempFilePath); |
||||
try { |
||||
Group targetGroup = getTargetGroup(); |
||||
if (file.exists() && targetGroup.installUniqueIdModule(file)) { |
||||
ShareUtils.recordInstallTime(file.getName(), System.currentTimeMillis()); |
||||
ComponentCollector.getInstance().collectCmpDownLoad(widget.getUuid()); |
||||
} |
||||
} catch (IOException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
private Group getTargetGroup() { |
||||
return DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); |
||||
} |
||||
|
||||
@Override |
||||
public void cancel() { |
||||
if (worker != null) { |
||||
worker.cancel(false); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,179 @@
|
||||
package com.fr.design.mainframe.share.ui.online.installation; |
||||
|
||||
import com.fr.design.extra.Process; |
||||
import com.fr.design.mainframe.share.ui.base.ImitationProgress; |
||||
import com.fr.design.mainframe.share.util.DownloadUtils; |
||||
import com.fr.design.mainframe.share.util.InstallUtils; |
||||
import com.fr.design.mainframe.share.util.ShareComponentUtils; |
||||
import com.fr.form.share.Group; |
||||
import com.fr.form.share.bean.OnlineShareWidget; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StableUtils; |
||||
import org.jetbrains.annotations.Nullable; |
||||
|
||||
import javax.swing.SwingWorker; |
||||
import java.io.File; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.concurrent.ExecutionException; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/5 |
||||
*/ |
||||
public class ComponentsPackageInstallation extends AsyncInstallation { |
||||
private final OnlineShareWidget packageWidget; |
||||
private final int childrenCount; |
||||
private ImitationThread imitationThread; |
||||
private DownLoadSwingWorker worker; |
||||
|
||||
public ComponentsPackageInstallation(OnlineShareWidget packageWidget, int childrenCount) { |
||||
this.packageWidget = packageWidget; |
||||
this.childrenCount = childrenCount; |
||||
} |
||||
|
||||
@Override |
||||
public void install() { |
||||
|
||||
final Process<Double> downloadProcess = new Process<Double>() { |
||||
@Override |
||||
public void process(Double value) { |
||||
notifyProgress(0.8 * value); |
||||
} |
||||
}; |
||||
final Process<Double> installProcess = new Process<Double>() { |
||||
|
||||
@Override |
||||
public void process(Double value) { |
||||
notifyProgress(0.8 + 0.2 * value); |
||||
} |
||||
}; |
||||
|
||||
downloadProcess.process(0.0D); |
||||
|
||||
//假进度线程
|
||||
final ImitationProgress imitationProgress = new ImitationProgress(downloadProcess, childrenCount); |
||||
imitationThread = new ImitationThread(imitationProgress); |
||||
imitationThread.setName("Component-ImitationProcessThread"); |
||||
|
||||
//下载线程
|
||||
worker = new DownLoadSwingWorker(installProcess, packageWidget); |
||||
|
||||
imitationThread.start(); |
||||
worker.execute(); |
||||
} |
||||
|
||||
@Override |
||||
public void cancel() { |
||||
if (imitationThread != null) { |
||||
imitationThread.interrupt(); |
||||
} |
||||
if (worker != null) { |
||||
worker.cancel(false); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 假进度线程 |
||||
*/ |
||||
private static class ImitationThread extends Thread { |
||||
|
||||
private final ImitationProgress imitationProgress; |
||||
|
||||
public ImitationThread(ImitationProgress progress) { |
||||
imitationProgress = progress; |
||||
} |
||||
|
||||
@Override |
||||
public void run() { |
||||
imitationProgress.start(); |
||||
} |
||||
|
||||
public void complete() { |
||||
imitationProgress.completed(); |
||||
this.interrupt(); |
||||
} |
||||
|
||||
public void stopThread() { |
||||
imitationProgress.stop(); |
||||
this.interrupt(); |
||||
} |
||||
} |
||||
|
||||
private class DownLoadSwingWorker extends SwingWorker<Group, Void> { |
||||
final Process<Double> installProcess; |
||||
final OnlineShareWidget onlineShareWidget; |
||||
|
||||
public DownLoadSwingWorker(Process<Double> installProcess, OnlineShareWidget onlineShareWidget) { |
||||
this.installProcess = installProcess; |
||||
this.onlineShareWidget = onlineShareWidget; |
||||
} |
||||
|
||||
@Override |
||||
@Nullable |
||||
protected Group doInBackground() { |
||||
final String filePath; |
||||
List<String> failureList = new ArrayList<>(); |
||||
try { |
||||
filePath = DownloadUtils.downloadPackage(onlineShareWidget.getId(), onlineShareWidget.getName(), DownLoadSwingWorker.this::isCancelled); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
imitationThread.stopThread(); |
||||
return null; |
||||
} |
||||
if (this.isCancelled()) { |
||||
imitationThread.stopThread(); |
||||
StableUtils.deleteFile(new File(filePath)); |
||||
return null; |
||||
} |
||||
|
||||
//等待假进度线程结束
|
||||
imitationThread.complete(); |
||||
try { |
||||
imitationThread.join(); |
||||
} catch (InterruptedException ignore) { |
||||
} |
||||
|
||||
//再判断一次
|
||||
if (this.isCancelled()) { |
||||
StableUtils.deleteFile(new File(filePath)); |
||||
return null; |
||||
} |
||||
ShareComponentUtils.checkReadMe(); |
||||
//安装
|
||||
File file = new File(filePath); |
||||
installProcess.process(0.0D); |
||||
InstallUtils.InstallResult result = null; |
||||
try { |
||||
if (file.exists()) { |
||||
result = InstallUtils.installReusFile(file, System.currentTimeMillis(), failureList, installProcess); |
||||
} |
||||
} finally { |
||||
//删掉下载组件的目录
|
||||
StableUtils.deleteFile(file); |
||||
} |
||||
return result == null ? null : result.group; |
||||
} |
||||
|
||||
@Override |
||||
protected void done() { |
||||
Group group = null; |
||||
try { |
||||
group = get(); |
||||
} catch (InterruptedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
Thread.currentThread().interrupt(); |
||||
} catch (ExecutionException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
|
||||
notifyProgress(0.0D); |
||||
if (group != null) { |
||||
notifySuccess(); |
||||
} else { |
||||
notifyFailed(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,10 @@
|
||||
package com.fr.design.mainframe.share.ui.online.installation; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/5 |
||||
*/ |
||||
public interface Installation { |
||||
void install(); |
||||
} |
@ -0,0 +1,202 @@
|
||||
package com.fr.design.mainframe.share.ui.online.installation; |
||||
|
||||
import com.fr.base.theme.FormTheme; |
||||
import com.fr.base.theme.FormThemeConfig; |
||||
import com.fr.base.theme.TemplateTheme; |
||||
import com.fr.base.theme.TemplateThemeConfig; |
||||
import com.fr.design.DesignerEnvManager; |
||||
import com.fr.design.dialog.FineJOptionPane; |
||||
import com.fr.design.file.HistoryTemplateListCache; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.login.DesignerLoginHelper; |
||||
import com.fr.design.login.DesignerLoginSource; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.mainframe.JTemplate; |
||||
import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; |
||||
import com.fr.design.mainframe.share.util.DownloadUtils; |
||||
import com.fr.design.mainframe.theme.dialog.TemplateThemeUsingDialog; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.transaction.CallBackAdaptor; |
||||
import com.fr.workspace.WorkContext; |
||||
|
||||
import javax.swing.JOptionPane; |
||||
import javax.swing.SwingWorker; |
||||
import java.awt.Window; |
||||
import java.awt.event.WindowAdapter; |
||||
import java.awt.event.WindowEvent; |
||||
import java.util.concurrent.ExecutionException; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/5 |
||||
*/ |
||||
public class TemplateThemeInstallation extends AsyncInstallation { |
||||
private final String themePath; |
||||
private SwingWorker<FormTheme, Void> worker; |
||||
|
||||
public TemplateThemeInstallation(String themePath) { |
||||
this.themePath = themePath; |
||||
} |
||||
|
||||
@Override |
||||
public void install() { |
||||
fetchTheme(); |
||||
} |
||||
|
||||
private void fetchTheme() { |
||||
if (!checkAuthority()) { |
||||
onThemeFetched(null); |
||||
return; |
||||
} |
||||
|
||||
worker = new SwingWorker<FormTheme, Void>() { |
||||
|
||||
@Override |
||||
protected FormTheme doInBackground() { |
||||
return DownloadUtils.downloadThemeFile(themePath); |
||||
} |
||||
|
||||
@Override |
||||
protected void done() { |
||||
FormTheme theme = null; |
||||
try { |
||||
theme = get(); |
||||
} catch (InterruptedException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
Thread.currentThread().interrupt(); |
||||
} catch (ExecutionException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
|
||||
onThemeFetched(theme); |
||||
} |
||||
}; |
||||
worker.execute(); |
||||
} |
||||
|
||||
private boolean checkAuthority() { |
||||
if (!WorkContext.getCurrent().isRoot()) { |
||||
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), |
||||
Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_No_Authority_Tip_Message"), |
||||
Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_No_Authority_Tip_Title"), |
||||
JOptionPane.WARNING_MESSAGE); |
||||
return false; |
||||
} |
||||
|
||||
String userName = DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); |
||||
if (StringUtils.isEmpty(userName)) { |
||||
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL); |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
public void onThemeFetched(FormTheme theme) { |
||||
if (theme == null) { |
||||
notifyFailed(); |
||||
return; |
||||
} |
||||
saveTheme(theme); |
||||
} |
||||
|
||||
private FormTheme ensureThemeHasUniqueName(FormTheme theme, String expectedName) { |
||||
if (!FormThemeConfig.getInstance().contains(expectedName)) { |
||||
theme.setName(expectedName); |
||||
return theme; |
||||
} else { |
||||
String newName = (String) FineJOptionPane.showInputDialog( |
||||
DesignerContext.getDesignerFrame(), |
||||
Toolkit.i18nText("Fine-Design_Share_Rename_Suitable_Theme_Tip"), |
||||
Toolkit.i18nText("Fine-Design_Basic_Rename"), |
||||
FineJOptionPane.QUESTION_MESSAGE, null, null, |
||||
expectedName); |
||||
|
||||
return StringUtils.isEmpty(newName) ? null : ensureThemeHasUniqueName(theme, newName); |
||||
} |
||||
} |
||||
|
||||
private void saveTheme(FormTheme theme) { |
||||
final FormTheme uniqueNamedTheme = ensureThemeHasUniqueName(theme, theme.getName()); |
||||
if (uniqueNamedTheme != null) { |
||||
FormThemeConfig.getInstance().addTheme(theme, true, new CallBackAdaptor() { |
||||
@Override |
||||
public void afterCommit() { |
||||
super.afterCommit(); |
||||
onThemeSaved(uniqueNamedTheme); |
||||
} |
||||
|
||||
@Override |
||||
public void afterRollback() { |
||||
super.afterRollback(); |
||||
onThemeSaved(null); |
||||
} |
||||
}); |
||||
} else { |
||||
onThemeSaved(null); |
||||
} |
||||
} |
||||
|
||||
public void onThemeSaved(FormTheme theme) { |
||||
if (theme == null) { |
||||
notifyFailed(); |
||||
return; |
||||
} |
||||
|
||||
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); |
||||
if (currentTemplate.getUsingTemplateThemeConfig() instanceof FormThemeConfig) { |
||||
TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog(); |
||||
dialog.addWindowListener(new UsingDialogAdapter(theme, currentTemplate)); |
||||
dialog.setVisible(true); |
||||
} else { |
||||
FineJOptionPane.showConfirmDialog( |
||||
MiniComponentShopDialog.getInstance().getContentPane(), |
||||
Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_Success_Tip"), |
||||
"", |
||||
FineJOptionPane.YES_NO_OPTION |
||||
); |
||||
} |
||||
notifySuccess(); |
||||
} |
||||
|
||||
public void applyTheme(JTemplate<?, ?> template, final String name, Window dialog) { |
||||
TemplateThemeConfig<? extends TemplateTheme> config = template.getUsingTemplateThemeConfig(); |
||||
TemplateTheme theme = config.cachedFetch(name); |
||||
template.setTemplateTheme(theme); |
||||
dialog.repaint(); |
||||
} |
||||
|
||||
@Override |
||||
public void cancel() { |
||||
if (worker != null) { |
||||
worker.cancel(true); |
||||
} |
||||
} |
||||
|
||||
private class UsingDialogAdapter extends WindowAdapter { |
||||
private final FormTheme theme; |
||||
private final JTemplate<?, ?> currentFormTemplate; |
||||
|
||||
public UsingDialogAdapter(FormTheme theme, JTemplate<?, ?> currentFormTemplate) { |
||||
this.theme = theme; |
||||
this.currentFormTemplate = currentFormTemplate; |
||||
} |
||||
|
||||
@Override |
||||
public void windowOpened(WindowEvent e) { |
||||
super.windowOpened(e); |
||||
Window window = e.getWindow(); |
||||
int returnVal = FineJOptionPane.showConfirmDialog( |
||||
window, |
||||
Toolkit.i18nText("Fine-Design_Share_Apply_Suitable_Theme_Tip"), |
||||
Toolkit.i18nText("Fine-Design_Basic_Confirm"), |
||||
FineJOptionPane.OK_CANCEL_OPTION); |
||||
if (returnVal == JOptionPane.YES_OPTION) { |
||||
applyTheme(currentFormTemplate, theme.getName(), window); |
||||
} |
||||
window.removeWindowListener(this); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,124 @@
|
||||
package com.fr.design.mainframe.share.ui.online.mini; |
||||
|
||||
import com.fr.design.dialog.BasicDialog; |
||||
import com.fr.design.dialog.UIDialog; |
||||
import com.fr.design.mainframe.share.mini.MiniShopDisposingChecker; |
||||
import com.fr.general.IOUtils; |
||||
|
||||
import javax.swing.JFrame; |
||||
import java.awt.Container; |
||||
import java.awt.Dimension; |
||||
import java.awt.Window; |
||||
import java.awt.event.WindowEvent; |
||||
import java.awt.event.WindowListener; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/4 |
||||
*/ |
||||
public class MiniComponentShopDialog { |
||||
private static class HOLDER { |
||||
private static final MiniComponentShopDialog singleton = new MiniComponentShopDialog(); |
||||
} |
||||
public static MiniComponentShopDialog getInstance() { |
||||
return MiniComponentShopDialog.HOLDER.singleton; |
||||
} |
||||
|
||||
private final Set<WindowListener> windowListeners = new HashSet<>(); |
||||
private JFrame frame; |
||||
|
||||
private JFrame createFrame() { |
||||
final JFrame frame = new JFrame(); |
||||
final MiniComponentShopPane shopPane = new MiniComponentShopPane(); |
||||
|
||||
frame.setSize(1200, 800); |
||||
frame.add(shopPane); |
||||
frame.setResizable(false); |
||||
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); |
||||
frame.addWindowListener(new WindowListener() { |
||||
@Override |
||||
public void windowOpened(WindowEvent e) { |
||||
for (WindowListener listener: windowListeners) { |
||||
listener.windowOpened(e); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void windowClosing(WindowEvent e) { |
||||
for (WindowListener listener : windowListeners) { |
||||
listener.windowClosing(e); |
||||
} |
||||
if (MiniShopDisposingChecker.check(frame.getContentPane())) { |
||||
e.getWindow().dispose(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void windowClosed(WindowEvent e) { |
||||
for (WindowListener listener: windowListeners) { |
||||
listener.windowClosed(e); |
||||
} |
||||
getInstance().frame = null; |
||||
shopPane.dispose(); |
||||
} |
||||
|
||||
@Override |
||||
public void windowIconified(WindowEvent e) { |
||||
for (WindowListener listener: windowListeners) { |
||||
listener.windowIconified(e); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void windowDeiconified(WindowEvent e) { |
||||
for (WindowListener listener: windowListeners) { |
||||
listener.windowDeiconified(e); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void windowActivated(WindowEvent e) { |
||||
for (WindowListener listener: windowListeners) { |
||||
listener.windowActivated(e); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void windowDeactivated(WindowEvent e) { |
||||
for (WindowListener listener: windowListeners) { |
||||
listener.windowDeactivated(e); |
||||
} |
||||
} |
||||
}); |
||||
return frame; |
||||
} |
||||
|
||||
public void show() { |
||||
if (frame == null) { |
||||
frame = createFrame(); |
||||
} |
||||
frame.setVisible(true); |
||||
} |
||||
|
||||
public Container getContentPane() { |
||||
if (frame != null) { |
||||
return frame.getContentPane(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public Window getWindow() { |
||||
return frame; |
||||
} |
||||
|
||||
public void addWindowAdapter(WindowListener windowListener) { |
||||
windowListeners.add(windowListener); |
||||
if (frame != null) { |
||||
frame.removeWindowListener(windowListener); |
||||
frame.addWindowListener(windowListener); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,68 @@
|
||||
package com.fr.design.mainframe.share.ui.online.mini; |
||||
|
||||
import com.fr.design.DesignerEnvManager; |
||||
import com.fr.design.mainframe.share.ui.online.mini.bridge.ComposedNativeBridges; |
||||
import com.fr.design.mainframe.share.util.OnlineShopUtils; |
||||
import com.fr.design.ui.ModernUIPane; |
||||
import com.fr.design.upm.event.CertificateEvent; |
||||
import com.fr.event.Event; |
||||
import com.fr.event.EventDispatcher; |
||||
import com.fr.event.Listener; |
||||
import com.teamdev.jxbrowser.chromium.JSObject; |
||||
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; |
||||
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; |
||||
|
||||
import javax.swing.JOptionPane; |
||||
import javax.swing.JPanel; |
||||
import java.awt.BorderLayout; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/12/20 |
||||
*/ |
||||
public class MiniComponentShopPane extends JPanel { |
||||
private final ModernUIPane<Object> modernUIPane; |
||||
private final Listener<String> loginListener; |
||||
private final Listener<String> logoutListener; |
||||
|
||||
public MiniComponentShopPane() { |
||||
setLayout(new BorderLayout()); |
||||
DesignerEnvManager.getEnvManager().setOpenDebug(true); |
||||
modernUIPane = new ModernUIPane.Builder<>() |
||||
.withURL(OnlineShopUtils.getWebMiniShopPath()) |
||||
.prepare(new ScriptContextAdapter() { |
||||
@Override |
||||
public void onScriptContextCreated(ScriptContextEvent event) { |
||||
super.onScriptContextCreated(event); |
||||
JSObject window = event.getBrowser().executeJavaScriptAndReturnValue("window").asObject(); |
||||
window.asObject().setProperty("ShopHelper", new ComposedNativeBridges(window, JOptionPane.getFrameForComponent(MiniComponentShopPane.this))); |
||||
} |
||||
}) |
||||
.build(); |
||||
|
||||
add(modernUIPane, BorderLayout.CENTER); |
||||
|
||||
loginListener = new Listener<String>() { |
||||
@Override |
||||
public void on(Event event, String param) { |
||||
modernUIPane.redirect(OnlineShopUtils.getWebMiniShopPath()); |
||||
} |
||||
}; |
||||
logoutListener = new Listener<String>() { |
||||
@Override |
||||
public void on(Event event, String param) { |
||||
modernUIPane.redirect(OnlineShopUtils.getWebMiniShopPath()); |
||||
} |
||||
}; |
||||
|
||||
EventDispatcher.listen(CertificateEvent.LOGIN, loginListener); |
||||
EventDispatcher.listen(CertificateEvent.LOGOUT, logoutListener); |
||||
} |
||||
|
||||
public void dispose() { |
||||
modernUIPane.disposeBrowser(); |
||||
EventDispatcher.stopListen(loginListener); |
||||
EventDispatcher.stopListen(logoutListener); |
||||
} |
||||
} |
@ -0,0 +1,26 @@
|
||||
package com.fr.design.mainframe.share.ui.online.mini.bridge; |
||||
|
||||
import com.teamdev.jxbrowser.chromium.JSAccessible; |
||||
import com.teamdev.jxbrowser.chromium.JSObject; |
||||
|
||||
import java.awt.Window; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/12/20 |
||||
*/ |
||||
public class ComposedNativeBridges { |
||||
@JSAccessible |
||||
public final NativeBrowserBridge Browser; |
||||
@JSAccessible |
||||
public final NativeAuthBridge Auth; |
||||
@JSAccessible |
||||
public final NativeProductBridge Product; |
||||
|
||||
public ComposedNativeBridges(JSObject window, Window nativeWindow) { |
||||
this.Browser = new NativeBrowserBridge(nativeWindow); |
||||
this.Auth = new NativeAuthBridge(); |
||||
this.Product = new NativeProductBridge(window); |
||||
} |
||||
} |
@ -0,0 +1,34 @@
|
||||
package com.fr.design.mainframe.share.ui.online.mini.bridge; |
||||
|
||||
import com.fr.design.DesignerEnvManager; |
||||
import com.fr.design.bridge.exec.JSBridge; |
||||
import com.fr.design.login.DesignerLoginHelper; |
||||
import com.fr.design.login.DesignerLoginSource; |
||||
import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; |
||||
import com.teamdev.jxbrowser.chromium.JSAccessible; |
||||
|
||||
import java.awt.Window; |
||||
import java.util.HashMap; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/12/20 |
||||
*/ |
||||
public class NativeAuthBridge { |
||||
@JSAccessible |
||||
@JSBridge |
||||
public String getLoginUsername() { |
||||
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
public void goLogin() { |
||||
Window parentWindow = MiniComponentShopDialog.getInstance().getWindow(); |
||||
if (parentWindow != null) { |
||||
parentWindow.toFront(); |
||||
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL, new HashMap<>(), parentWindow); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,25 @@
|
||||
package com.fr.design.mainframe.share.ui.online.mini.bridge; |
||||
|
||||
import com.fr.design.bridge.exec.JSBridge; |
||||
import com.teamdev.jxbrowser.chromium.JSAccessible; |
||||
|
||||
import java.awt.Window; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/12/20 |
||||
*/ |
||||
public class NativeBrowserBridge { |
||||
private final Window nativeWindow; |
||||
|
||||
public NativeBrowserBridge(Window nativeWindow) { |
||||
this.nativeWindow = nativeWindow; |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
public void dispose() { |
||||
this.nativeWindow.dispose(); |
||||
} |
||||
} |
@ -0,0 +1,287 @@
|
||||
|
||||
package com.fr.design.mainframe.share.ui.online.mini.bridge; |
||||
|
||||
import com.fr.design.bridge.exec.JSBridge; |
||||
import com.fr.design.dialog.FineJOptionPane; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.mainframe.EastRegionContainerPane; |
||||
import com.fr.design.mainframe.FormWidgetDetailPane; |
||||
import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; |
||||
import com.fr.design.mainframe.share.ui.online.installation.AsyncInstallation; |
||||
import com.fr.design.mainframe.share.ui.online.installation.ComponentInstallation; |
||||
import com.fr.design.mainframe.share.ui.online.installation.ComponentsPackageInstallation; |
||||
import com.fr.design.mainframe.share.ui.online.installation.TemplateThemeInstallation; |
||||
import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; |
||||
import com.fr.form.share.Group; |
||||
import com.fr.form.share.SharableWidgetProvider; |
||||
import com.fr.form.share.bean.OnlineShareWidget; |
||||
import com.fr.form.share.group.DefaultShareGroupManager; |
||||
import com.fr.json.JSONArray; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.stable.StringUtils; |
||||
import com.teamdev.jxbrowser.chromium.JSAccessible; |
||||
import com.teamdev.jxbrowser.chromium.JSObject; |
||||
|
||||
import javax.swing.JOptionPane; |
||||
import javax.swing.SwingUtilities; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/12/20 |
||||
*/ |
||||
public class NativeProductBridge { |
||||
private final JSObject window; |
||||
|
||||
public NativeProductBridge(JSObject window) { |
||||
this.window = window; |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
public String getDownloadedProductIds() { |
||||
Set<String> uuidList = new HashSet<>(); |
||||
for (Group group : DefaultShareGroupManager.getInstance().getAllGroup()) { |
||||
SharableWidgetProvider[] widgetProviderList = group.getAllBindInfoList(); |
||||
for (SharableWidgetProvider widget: widgetProviderList) { |
||||
if (StringUtils.isNotEmpty(widget.getId())) { |
||||
uuidList.add(widget.getId()); |
||||
} |
||||
} |
||||
} |
||||
JSONArray array = JSONArray.create(uuidList); |
||||
return array.toString(); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
public Object createProductDownloadTask(String json) { |
||||
return new ComponentInstallationTask(window, json); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
public Object createProductsPackageDownloadTask(String json) { |
||||
return new ComponentsPackageInstallationTask(window, json); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
public Object createTemplateThemeDownloadTask(String themePath) { |
||||
return new TemplateThemeInstallationTask(window, themePath); |
||||
} |
||||
|
||||
public static class ComponentInstallationTask extends NativeTaskBridge { |
||||
private final OnlineShareWidget widget; |
||||
private final ComponentInstallation action; |
||||
|
||||
public ComponentInstallationTask(JSObject window, String widgetJson) { |
||||
super(window); |
||||
|
||||
JSONObject object = new JSONObject(widgetJson); |
||||
widget = OnlineShareWidget.parseFromJSONObject(object); |
||||
action = new ComponentInstallation(widget); |
||||
action.setActionListener(new AsyncInstallation.AsyncActionListener() { |
||||
@Override |
||||
public void onProgress(double value) { |
||||
fireProgressEvent(Double.toString(value)); |
||||
} |
||||
|
||||
@Override |
||||
public void onSuccess() { |
||||
fireSuccessEvent(null); |
||||
if (!DesignerContext.getDesignerFrame().isActive()) { |
||||
LocalWidgetRepoPane.getInstance().refreshPane(); |
||||
FormWidgetDetailPane.getInstance().switch2Local(); |
||||
EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onFailed() { |
||||
fireFailureEvent(null); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
@Override |
||||
public void execute() { |
||||
super.execute(); |
||||
SwingUtilities.invokeLater(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
boolean allowedDownload = true; |
||||
if (!widget.isCompatibleWithCurrentEnv()) { |
||||
int result = FineJOptionPane.showConfirmDialog( |
||||
MiniComponentShopDialog.getInstance().getContentPane(), |
||||
Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Incompatible_Component_Tip"), |
||||
"", |
||||
FineJOptionPane.YES_NO_OPTION |
||||
); |
||||
allowedDownload = result == JOptionPane.YES_OPTION; |
||||
} |
||||
if (allowedDownload) { |
||||
fireStartEvent(null); |
||||
action.install(); |
||||
} else { |
||||
fireFailureEvent(null); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
@Override |
||||
public void cancel() { |
||||
super.cancel(); |
||||
SwingUtilities.invokeLater(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
action.cancel(); |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
|
||||
public static class ComponentsPackageInstallationTask extends NativeTaskBridge { |
||||
|
||||
private final ComponentsPackageInstallation action; |
||||
private final OnlineShareWidget widget; |
||||
private final int childrenCount; |
||||
|
||||
public ComponentsPackageInstallationTask(JSObject window, String widgetJson) { |
||||
super(window); |
||||
JSONObject object = new JSONObject(widgetJson); |
||||
widget = OnlineShareWidget.parseFromJSONObject(object); |
||||
childrenCount = object.optInt("pkgsize", 0); |
||||
action = new ComponentsPackageInstallation(widget, childrenCount); |
||||
action.setActionListener(new AsyncInstallation.AsyncActionListener() { |
||||
@Override |
||||
public void onProgress(double value) { |
||||
fireProgressEvent(Double.toString(value)); |
||||
} |
||||
|
||||
@Override |
||||
public void onSuccess() { |
||||
fireSuccessEvent(null); |
||||
if (!DesignerContext.getDesignerFrame().isActive()) { |
||||
LocalWidgetRepoPane.getInstance().refreshPane(); |
||||
FormWidgetDetailPane.getInstance().switch2Local(); |
||||
EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onFailed() { |
||||
fireFailureEvent(null); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
@Override |
||||
public void execute() { |
||||
super.execute(); |
||||
SwingUtilities.invokeLater(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
boolean allowedDownload; |
||||
if (!widget.isCompatibleWithCurrentEnv()) { |
||||
int result = FineJOptionPane.showConfirmDialog( |
||||
MiniComponentShopDialog.getInstance().getContentPane(), |
||||
Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Incompatible_Components_Package_Tip", childrenCount), |
||||
"", |
||||
FineJOptionPane.YES_NO_OPTION |
||||
); |
||||
allowedDownload = result == JOptionPane.YES_OPTION; |
||||
} else { |
||||
int result = FineJOptionPane.showConfirmDialog( |
||||
MiniComponentShopDialog.getInstance().getContentPane(), |
||||
Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Components_Package_Tip", childrenCount), |
||||
"", |
||||
FineJOptionPane.YES_NO_OPTION |
||||
); |
||||
allowedDownload = result == JOptionPane.YES_OPTION; |
||||
} |
||||
if (allowedDownload) { |
||||
fireStartEvent(null); |
||||
action.install(); |
||||
} else { |
||||
fireFailureEvent(null); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
@Override |
||||
public void cancel() { |
||||
super.cancel(); |
||||
SwingUtilities.invokeLater(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
action.cancel(); |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
|
||||
public static class TemplateThemeInstallationTask extends NativeTaskBridge { |
||||
private final TemplateThemeInstallation action; |
||||
public TemplateThemeInstallationTask(JSObject window, String themePath) { |
||||
super(window); |
||||
action = new TemplateThemeInstallation(themePath); |
||||
action.setActionListener(new AsyncInstallation.AsyncActionListener() { |
||||
@Override |
||||
public void onProgress(double value) { |
||||
fireProgressEvent(Double.toString(value)); |
||||
} |
||||
|
||||
@Override |
||||
public void onSuccess() { |
||||
fireSuccessEvent(null); |
||||
} |
||||
|
||||
@Override |
||||
public void onFailed() { |
||||
fireFailureEvent(null); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
@Override |
||||
public void execute() { |
||||
super.execute(); |
||||
SwingUtilities.invokeLater(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
fireStartEvent(null); |
||||
action.install(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@JSAccessible |
||||
@JSBridge |
||||
@Override |
||||
public void cancel() { |
||||
super.cancel(); |
||||
SwingUtilities.invokeLater(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
action.cancel(); |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,89 @@
|
||||
package com.fr.design.mainframe.share.ui.online.mini.bridge; |
||||
|
||||
import com.fr.design.bridge.exec.JSBridge; |
||||
import com.fr.design.mainframe.share.mini.MiniShopNativeTask; |
||||
import com.fr.design.mainframe.share.mini.MiniShopNativeTaskManager; |
||||
import com.teamdev.jxbrowser.chromium.JSAccessible; |
||||
import com.teamdev.jxbrowser.chromium.JSFunction; |
||||
import com.teamdev.jxbrowser.chromium.JSObject; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2021/12/20 |
||||
*/ |
||||
public class NativeTaskBridge implements MiniShopNativeTask { |
||||
|
||||
private final JSObject window; |
||||
|
||||
protected JSFunction startCb; |
||||
protected JSFunction progressCb; |
||||
protected JSFunction successCb; |
||||
protected JSFunction failureCb; |
||||
|
||||
public NativeTaskBridge(JSObject window) { |
||||
this.window = window; |
||||
} |
||||
|
||||
@JSBridge |
||||
@JSAccessible |
||||
public void setStartCallback(JSFunction cb) { |
||||
this.startCb = cb; |
||||
} |
||||
|
||||
@JSBridge |
||||
@JSAccessible |
||||
public void setProgressCallback(JSFunction cb) { |
||||
this.progressCb = cb; |
||||
} |
||||
|
||||
@JSBridge |
||||
@JSAccessible |
||||
public void setSuccessCallback(JSFunction cb) { |
||||
this.successCb = cb; |
||||
} |
||||
|
||||
@JSBridge |
||||
@JSAccessible |
||||
public void setFailureCallback(JSFunction cb) { |
||||
this.failureCb = cb; |
||||
} |
||||
|
||||
@JSBridge |
||||
@JSAccessible |
||||
@Override |
||||
public void execute() { |
||||
} |
||||
|
||||
@JSBridge |
||||
@JSAccessible |
||||
@Override |
||||
public void cancel() { |
||||
MiniShopNativeTaskManager.getInstance().removeCompletedTask(this); |
||||
} |
||||
|
||||
|
||||
protected void fireStartEvent(String event) { |
||||
MiniShopNativeTaskManager.getInstance().addStartedTask(this); |
||||
if (this.startCb != null) { |
||||
this.startCb.invoke(window, event); |
||||
} |
||||
} |
||||
protected void fireProgressEvent(String event) { |
||||
if (this.progressCb != null) { |
||||
this.progressCb.invoke(window, event); |
||||
} |
||||
} |
||||
protected void fireSuccessEvent(String event) { |
||||
MiniShopNativeTaskManager.getInstance().removeCompletedTask(this); |
||||
if (this.successCb != null) { |
||||
this.successCb.invoke(window, event); |
||||
} |
||||
} |
||||
protected void fireFailureEvent(String event) { |
||||
MiniShopNativeTaskManager.getInstance().removeCompletedTask(this); |
||||
if (this.failureCb != null) { |
||||
this.failureCb.invoke(window, event); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,15 @@
|
||||
package com.fr.design.deeplink; |
||||
|
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/6 |
||||
*/ |
||||
public abstract class DeepLink { |
||||
|
||||
public abstract boolean accept(String url, String host, String path, Map<String, Object> params); |
||||
|
||||
public abstract void run(String url, String host, String path, Map<String, Object> params); |
||||
} |
@ -0,0 +1,133 @@
|
||||
package com.fr.design.deeplink; |
||||
|
||||
import com.fr.design.constants.DesignerLaunchStatus; |
||||
import com.fr.design.startup.FineStartupNotificationFactory; |
||||
import com.fr.design.startup.FineStartupNotificationProvider; |
||||
import com.fr.event.Event; |
||||
import com.fr.event.EventDispatcher; |
||||
import com.fr.event.Listener; |
||||
import com.fr.event.Null; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.org.apache.http.NameValuePair; |
||||
import com.fr.web.URLUtils; |
||||
|
||||
import javax.swing.SwingUtilities; |
||||
import java.io.IOException; |
||||
import java.net.MalformedURLException; |
||||
import java.net.URL; |
||||
import java.net.URLConnection; |
||||
import java.net.URLStreamHandler; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/6 |
||||
*/ |
||||
public class DeepLinkManager { |
||||
|
||||
private DeepLinkManager(){} |
||||
private static final DeepLinkManager instance = new DeepLinkManager(); |
||||
public static DeepLinkManager getInstance(){ |
||||
return instance; |
||||
} |
||||
|
||||
private String pendingURL; |
||||
|
||||
private final List<DeepLink> deepLinkList = new ArrayList<>(); |
||||
|
||||
private boolean isDesignerStartUpCompleted = false; |
||||
|
||||
private void register(DeepLink deepLink) { |
||||
if (deepLink != null) { |
||||
deepLinkList.add(deepLink); |
||||
} |
||||
} |
||||
|
||||
public void prepare() { |
||||
register(new TemplateThemeInstallationDeepLink()); |
||||
|
||||
FineStartupNotificationFactory.getNotification() |
||||
.registerStartupListener(new FineStartupNotificationProvider.Listener() { |
||||
@Override |
||||
public void startupPerformed(String parameters) { |
||||
if (canAcceptNewURL()) { |
||||
acceptNewURL(parameters); |
||||
if (canConsumePendingURL()) { |
||||
consumePendingURL(); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
|
||||
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() { |
||||
@Override |
||||
public void on(Event event, Null param) { |
||||
isDesignerStartUpCompleted = true; |
||||
if (canConsumePendingURL()) { |
||||
consumePendingURL(); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private boolean canAcceptNewURL() { |
||||
return StringUtils.isEmpty(this.pendingURL); |
||||
} |
||||
|
||||
private void acceptNewURL(String url) { |
||||
this.pendingURL = url; |
||||
} |
||||
|
||||
private boolean canConsumePendingURL() { |
||||
return StringUtils.isNotEmpty(this.pendingURL) && isDesignerStartUpCompleted; |
||||
} |
||||
|
||||
private void consumePendingURL() { |
||||
String host = null; |
||||
String path = null; |
||||
Map<String, Object> params = new HashMap<>(); |
||||
|
||||
URL url = null; |
||||
try { |
||||
url = new URL(null, this.pendingURL, new URLStreamHandler() { |
||||
@Override |
||||
protected URLConnection openConnection(URL u) throws IOException { |
||||
return null; |
||||
} |
||||
}); |
||||
} catch (MalformedURLException ignored) {} |
||||
|
||||
if (url != null) { |
||||
host = url.getHost(); |
||||
path = url.getPath(); |
||||
|
||||
List<NameValuePair> pairs = URLUtils.parse(url.getQuery()); |
||||
for (NameValuePair pair: pairs) { |
||||
params.put(pair.getName(), pair.getValue()); |
||||
} |
||||
} |
||||
|
||||
FineLoggerFactory.getLogger().info("consume deep link: " + this.pendingURL); |
||||
performDeepLinks(this.pendingURL, host, path, params); |
||||
|
||||
this.pendingURL = null; |
||||
} |
||||
|
||||
private void performDeepLinks(String url, String host, String path, Map<String, Object> params) { |
||||
SwingUtilities.invokeLater(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
for (DeepLink deepLink: deepLinkList) { |
||||
if (deepLink.accept(url, host, path, params)) { |
||||
deepLink.run(url, host, path, params); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,53 @@
|
||||
package com.fr.design.deeplink; |
||||
|
||||
import com.fr.design.mainframe.share.ui.online.installation.Installation; |
||||
import com.fr.design.mainframe.share.ui.online.installation.TemplateThemeInstallation; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.EncodeConstants; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.springframework.web.util.UriUtils; |
||||
|
||||
import java.io.UnsupportedEncodingException; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author Starryi |
||||
* @version 1.0 |
||||
* Created by Starryi on 2022/1/10 |
||||
*/ |
||||
public class TemplateThemeInstallationDeepLink extends DeepLink { |
||||
public TemplateThemeInstallationDeepLink() { |
||||
} |
||||
private static class Holder { |
||||
public static TemplateThemeInstallationDeepLink INSTANCE = new TemplateThemeInstallationDeepLink(); |
||||
} |
||||
public static TemplateThemeInstallationDeepLink getInstance() { |
||||
return TemplateThemeInstallationDeepLink.Holder.INSTANCE; |
||||
} |
||||
|
||||
public static final String HOST = "template_theme"; |
||||
public static final String PATH = "/add"; |
||||
public static final String FILE_KEY = "file"; |
||||
|
||||
@Override |
||||
public boolean accept(String url, String host, String path, Map<String, Object> params) { |
||||
return host != null && StringUtils.equals(HOST, host) |
||||
&& path != null && StringUtils.equals(PATH, path) |
||||
&& params != null && params.containsKey(FILE_KEY) |
||||
; |
||||
} |
||||
|
||||
@Override |
||||
public void run(String url, String host, String path, Map<String, Object> params) { |
||||
String remoteFileAddress = (String) params.get(FILE_KEY); |
||||
try { |
||||
remoteFileAddress = UriUtils.decode(remoteFileAddress, EncodeConstants.ENCODING_UTF_8); |
||||
FineLoggerFactory.getLogger().info("TemplateThemeInstallationDeepLink: " + remoteFileAddress); |
||||
|
||||
Installation installation = new TemplateThemeInstallation(remoteFileAddress); |
||||
installation.install(); |
||||
} catch (UnsupportedEncodingException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue