📄 applicationlauncher.java
字号:
/*
* SSL-Explorer
*
* Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package com.sslexplorer.vpn.util;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.zip.Adler32;
import java.util.zip.CheckedInputStream;
public class ApplicationLauncher {
File installDir;
File sharedDir;
String typeName;
String name;
String ticket;
long totalBytesToDownload = 0;
Vector filesToDownload = new Vector();
Hashtable sharedFilesToDowload = new Hashtable();
String applicationStoreProtocol;
String applicationStoreHost;
String applicationStoreUser;
int applicationStorePort;
protected ApplicationLauncherEvents events;
protected Hashtable parameters;
Vector tunnels = new Vector();
Hashtable descriptorParams = new Hashtable();
boolean debug = false;
String localProxyURL;
ApplicationType type;
int shortcutId;
Hashtable replacements = new Hashtable();
Vector transformations = new Vector();
String dependencies;
public ApplicationLauncher(String applicationStoreProtocol, String applicationStoreUser, String applicationStoreHost,
int applicationStorePort, Hashtable parameters, ApplicationLauncherEvents events) {
this.applicationStoreProtocol = applicationStoreProtocol;
this.applicationStoreHost = applicationStoreHost;
this.applicationStoreUser = applicationStoreUser;
this.applicationStorePort = applicationStorePort;
this.parameters = parameters;
this.events = events;
}
public int getShortcutId() {
return shortcutId;
}
public void setLocalProxyURL(String localProxyURL) {
this.localProxyURL = localProxyURL;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public ApplicationType getApplicationType() {
return type;
}
public InputStream getApplicationDescriptor() throws IOException {
/**
* LDP - I've seperated this out so it can be overidden by the VPN
* client to use the Maverick HTTP client. We need to be able to use
* URL connection because this class is used to launch the VPN client
* itself when it does not have access to Maverick HTTP.
*/
URL descriptor = new URL(applicationStoreProtocol, applicationStoreHost,
applicationStorePort, "/getApplication.do");
URLConnection con;
con = descriptor.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
DataOutputStream out = new DataOutputStream(con.getOutputStream());
StringBuffer content = new StringBuffer();
Enumeration en = parameters.keys();
if (en.hasMoreElements()) {
String key = (String) en.nextElement();
content.append(key);
content.append("=");
content.append(URLEncoder.encode( (String) parameters.get(key)));
while (en.hasMoreElements()) {
key = (String) en.nextElement();
content.append("&");
content.append(key);
content.append("=");
content.append(URLEncoder.encode( (String) parameters.get(key)));
}
}
out.writeBytes(content.toString());
out.flush();
out.close();
return con.getInputStream();
}
public void prepare() throws IOException {
if (events != null)
events.debug("Checking parameters");
if (!parameters.containsKey("name"))
throw new IOException("name is a required parameter");
if (!parameters.containsKey("ticket"))
throw new IOException("ticket is a required parameter");
// Add a debug parameter if were debugging
if (debug) {
parameters.put("debug", "true");
}
if (parameters.contains("id")) {
shortcutId = Integer.parseInt((String) parameters.get("id"));
} else {
shortcutId = -1;
}
ticket = (String) parameters.get("ticket");
if (events != null)
events.debug("Storing ticket " + ticket);
XMLElement element = new XMLElement();
element.parseFromReader(new InputStreamReader(getApplicationDescriptor()));
if (events != null)
events.debug("Received a response from server");
if (!element.getName().equals("application") && !element.getName().equals("error")
&& !element.getName().equals("extension")) {
throw new IOException("URL does not point to an application descriptor");
} else if (element.getName().equals("error")) {
throw new IOException(element.getContent());
}
name = (String) element.getAttribute("extension");
if (name == null) {
name = (String) element.getAttribute("application");
}
typeName = (String) element.getAttribute("type");
//
try {
type = (ApplicationType) Class.forName(
"com.sslexplorer.vpn.util.types."
+ (String.valueOf(typeName.charAt(0)).toUpperCase() + typeName.substring(1))
+ "ApplicationType").newInstance();
} catch (Throwable t) {
throw new IOException("Failed to load the application description extension for application type of " + typeName + ".");
}
if (events != null)
events.debug("Application name is " + name);
if (events != null) {
events.processingDescriptor();
}
if (events != null)
events.debug("Creating install folder");
// This code attempts to detect the MSJVM and obtain the users profile
// directory so that it can be used as the users home.
String userHome = Utils.getHomeDirectory();
if (events != null)
events.debug("User home is " + userHome);
installDir = new File(userHome, ".sslexplorer" + File.separator + "applications" + File.separator + name);
sharedDir = new File(userHome, ".sslexplorer" + File.separator + "shared");
if (!installDir.exists()) {
installDir.mkdirs();
}
if (!sharedDir.exists()) {
sharedDir.mkdirs();
}
if (events != null)
events.debug("Installing to " + installDir.getAbsolutePath());
Enumeration e = element.enumerateChildren();
while (e.hasMoreElements()) {
XMLElement el = (XMLElement) e.nextElement();
if (el.getName().equalsIgnoreCase("files")) {
processFiles(el);
} else if (el.getName().equalsIgnoreCase("tunnel")) {
// This should contain the host and port of a tunnel that
// we need to create
createTunnel(el);
} else if (el.getName().equalsIgnoreCase("parameter")) {
addParameter(el);
} else if (el.getName().equalsIgnoreCase("messages")) {
// Ignore as its a server side element
} else if (el.getName().equalsIgnoreCase("description")) {
// Simply ignore.. should we throw an exception if an element is
// not known?
} else if (el.getName().equalsIgnoreCase("replacements")) {
FileReplacement replacement = new FileReplacement(installDir);
replacement.processReplacementXML(el, this);
replacements.put(replacement.getId(), replacement);
} else if(processLauncherElement(el)) {
// This allows us to override more element types in extended
// application launchers (i.e. registry parameters)
continue;
} else if(el.getName().equalsIgnoreCase("transform")) {
ParameterTransformation trans = new ParameterTransformation(el, this);
transformations.addElement(trans);
} else {
type.prepare(this, events, el);
}
}
downloadFiles();
if(events!=null)
events.debug("Applying parameter transformations");
for (Enumeration ep = transformations.elements(); ep.hasMoreElements();) {
ParameterTransformation trans = (ParameterTransformation) ep.nextElement();
trans.processTransformation();
}
if(events!=null)
events.debug("Creating replacements");
for (Enumeration ep = replacements.elements(); ep.hasMoreElements();) {
FileReplacement replacement = (FileReplacement) ep.nextElement();
replacement.createReplacementsFile(this);
}
if(events!=null)
events.debug("Replacements created, preparation of launcher complete.");
}
protected boolean processLauncherElement(XMLElement e) {
return false;
}
public String getName() {
return name;
}
public File getInstallDir() {
return installDir;
}
public void start() {
type.start();
}
private void addParameter(XMLElement e) throws IOException {
String parameter = (String) e.getAttribute("name");
String value = (String) e.getAttribute("value");
if (events != null) {
events.debug("Adding parameter " + parameter + " with value of " + value);
}
descriptorParams.put(parameter, value);
}
public void addParameter(String parameter, String value) {
if (events != null) {
events.debug("Adding parameter " + parameter + " with value of " + value);
}
descriptorParams.put(parameter, value);
}
public Vector getTunnels() {
return tunnels;
}
private void createTunnel(XMLElement e) throws IOException {
String hostname = (String) e.getAttribute("hostname");
String name = (String) e.getAttribute("name");
int port = Integer.parseInt((String) e.getAttribute("port"));
boolean usePreferredPort = !("false".equals(e.getAttribute("usePreferredPort")));
boolean singleConnection = !("false".equals(e.getAttribute("singleConnection")));
if (events != null) {
Tunnel tunnel = events.createTunnel(name, hostname, port, usePreferredPort, singleConnection);
if (tunnel != null)
tunnels.addElement(tunnel);
else
throw new IOException("Failed to create a required tunnel to " + hostname + ":" + port);
} else
throw new IOException("Tunnel required but no event handler is available");
}
public String replaceTokens(String str) {
str = replaceAllTokens(str, "${client:installDir}", installDir.getAbsolutePath());
str = replaceAllTokens(str, "${sslexplorer:user}", applicationStoreUser == null ? "" : applicationStoreUser);
str = replaceAllTokens(str, "${sslexplorer:host}", applicationStoreHost == null ? "" : applicationStoreHost);
str = replaceAllTokens(str, "${sslexplorer:port}", applicationStorePort == -1 ? "" : String.valueOf(applicationStorePort));
str = replaceAllTokens(str, "${sslexplorer:protocol}", applicationStoreProtocol == null ? "" : applicationStoreProtocol);
str = replaceAllTokens(str, "${client:localProxyURL}", localProxyURL == null ? "" : localProxyURL);
for (Enumeration e = descriptorParams.keys(); e.hasMoreElements();) {
String key = (String) e.nextElement();
String val = (String) descriptorParams.get(key);
str = replaceAllTokens(str, "${param:" + key + "}", val);
}
for (Enumeration e = tunnels.elements(); e.hasMoreElements();) {
Tunnel tunnel = (Tunnel) e.nextElement();
String paramHost = "${tunnel:" + tunnel.getName() + ".hostname}";
String paramPort = "${tunnel:" + tunnel.getName() + ".port}";
str = replaceAllTokens(str, paramHost, "localhost");
str = replaceAllTokens(str, paramPort, String.valueOf(tunnel.getSourcePort()));
}
return str;
}
static String replaceAllTokens(String source, String token, String value) {
int idx;
do {
idx = source.indexOf(token);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -