You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
7.9 KiB
265 lines
7.9 KiB
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.stable.os.OperatingSystem; |
|
import com.fr.start.common.DesignerStartupContext; |
|
import com.fr.third.org.apache.http.NameValuePair; |
|
import com.fr.web.URLUtils; |
|
|
|
import javax.swing.SwingUtilities; |
|
import java.awt.Color; |
|
import java.awt.Frame; |
|
import java.awt.event.WindowAdapter; |
|
import java.awt.event.WindowEvent; |
|
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 DeepLinkCore { |
|
|
|
protected DeepLinkCore(){} |
|
private static final DeepLinkCore instance = new DeepLinkCore(); |
|
public static DeepLinkCore getInstance(){ |
|
return instance; |
|
} |
|
|
|
private String pendingURL; |
|
|
|
private final List<DeepLinkPrepare> deepLinkPrepareList = new ArrayList<>(); |
|
|
|
private final List<DeepLink> deepLinkList = new ArrayList<>(); |
|
|
|
private boolean isDesignerStartupCompleted = false; |
|
|
|
public void register(DeepLink deepLink) { |
|
if (deepLink != null) { |
|
deepLinkList.add(deepLink); |
|
if (deepLink instanceof DeepLinkPrepare) { |
|
deepLinkPrepareList.add((DeepLinkPrepare) deepLink); |
|
} |
|
} |
|
} |
|
|
|
public void start(String[] args) { |
|
if (OperatingSystem.isWindows()) { |
|
if (args.length > 0) { |
|
receiveDeeplink(args[0]); |
|
} |
|
} |
|
|
|
if (OperatingSystem.isWindows() && args.length > 0) { |
|
receiveDeeplink(args[0]); |
|
} |
|
|
|
FineStartupNotificationFactory.getNotification() |
|
.registerStartupListener(new FineStartupNotificationProvider.Listener() { |
|
@Override |
|
public void startupPerformed(String parameters) { |
|
receiveDeeplink(parameters); |
|
} |
|
}); |
|
|
|
EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener<Null>() { |
|
@Override |
|
public void on(Event event, Null param) { |
|
EventDispatcher.stopListen(this); |
|
isDesignerStartupCompleted = true; |
|
if (canConsumePendingURL()) { |
|
consumePendingURL(); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
public void receiveDeeplink(String url) { |
|
if (canAcceptNewURL()) { |
|
acceptNewURL(url); |
|
if (canConsumePendingURL()) { |
|
consumePendingURL(); |
|
} |
|
} |
|
} |
|
|
|
public void receiveDeeplink2(String url) { |
|
if (canAcceptNewURL()) { |
|
acceptNewURL(url); |
|
if (canConsumePendingURL()) { |
|
consumePendingURL(); |
|
} else { |
|
Frame frame = new Frame("can not ConsumePendingURL"); |
|
frame.setSize(400, 400); |
|
frame.setBackground(Color.BLACK); |
|
frame.addWindowListener(new WindowAdapter() { |
|
public void windowClosing(WindowEvent windowEvent){ |
|
frame.dispose(); |
|
} |
|
}); |
|
frame.setVisible(true); |
|
} |
|
} else { |
|
Frame frame = new Frame("can not AcceptNewURL"); |
|
frame.setSize(400, 400); |
|
frame.setBackground(Color.BLACK); |
|
frame.addWindowListener(new WindowAdapter() { |
|
public void windowClosing(WindowEvent windowEvent){ |
|
frame.dispose(); |
|
} |
|
}); |
|
frame.setVisible(true); |
|
} |
|
} |
|
|
|
private boolean canAcceptNewURL() { |
|
return StringUtils.isEmpty(this.pendingURL); |
|
} |
|
|
|
private void acceptNewURL(String url) { |
|
this.pendingURL = url; |
|
|
|
UrlBean urlBean = UrlBean.create(this.pendingURL); |
|
for (DeepLinkPrepare deepLinkPrepare : deepLinkPrepareList) { |
|
deepLinkPrepare.prepare(urlBean.getUrl(), urlBean.getHost(), urlBean.getPath(), urlBean.getParams()); |
|
} |
|
} |
|
|
|
private boolean canConsumePendingURL() { |
|
return StringUtils.isNotEmpty(this.pendingURL) && isAvailableConsumingTime(); |
|
} |
|
|
|
/** |
|
* 是否是可用的消耗时机 |
|
* 满足任一即可 |
|
* 1-设计器已经启动 |
|
* 2-出在设计器启动页页面 |
|
* |
|
* @return 是/否 |
|
*/ |
|
private boolean isAvailableConsumingTime() { |
|
return isDesignerStartupCompleted || DesignerStartupContext.getInstance().isOnWaiting(); |
|
} |
|
|
|
private void consumePendingURL() { |
|
|
|
UrlBean urlBean = UrlBean.create(this.pendingURL); |
|
|
|
FineLoggerFactory.getLogger().info("consume deep link: " + this.pendingURL); |
|
performDeepLinks(urlBean.getUrl(), urlBean.getHost(), urlBean.getPath(), urlBean.getParams()); |
|
|
|
markPendingURLConsumed(); |
|
} |
|
|
|
/** |
|
* 符合条件的url才处理 |
|
* |
|
* @param url 接收到的url |
|
* @return true:处理; false:不处理 |
|
*/ |
|
public boolean accept(String url) { |
|
UrlBean urlBean = UrlBean.create(url); |
|
for (DeepLink deepLink: deepLinkList) { |
|
if (deepLink.accept(urlBean.getUrl(), urlBean.getHost(), urlBean.getPath(), urlBean.getParams())) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
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); |
|
} |
|
} |
|
} |
|
}); |
|
} |
|
|
|
private void markPendingURLConsumed() { |
|
this.pendingURL = null; |
|
} |
|
|
|
private static class UrlBean { |
|
|
|
private String url; |
|
|
|
private String host; |
|
|
|
private String path; |
|
|
|
private Map<String, Object> params; |
|
|
|
public UrlBean(String url, String host, String path, Map<String, Object> params) { |
|
this.url = url; |
|
this.host = host; |
|
this.path = path; |
|
this.params = params; |
|
} |
|
|
|
public String getUrl() { |
|
return url; |
|
} |
|
|
|
public String getHost() { |
|
return host; |
|
} |
|
|
|
public String getPath() { |
|
return path; |
|
} |
|
|
|
public Map<String, Object> getParams() { |
|
return params; |
|
} |
|
|
|
public static UrlBean create(String pendingUrl) { |
|
|
|
String host = null; |
|
String path = null; |
|
Map<String, Object> params = new HashMap<>(); |
|
|
|
URL url = null; |
|
try { |
|
url = new URL(null, 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()); |
|
} |
|
} |
|
return new UrlBean(pendingUrl, host, path, params); |
|
} |
|
} |
|
}
|
|
|