| /* | |
| * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved. | |
| * | |
| * This program and the accompanying materials are made available under the | |
| * terms of the Eclipse Public License v. 2.0, which is available at | |
| * http://www.eclipse.org/legal/epl-2.0. | |
| * | |
| * This Source Code may also be made available under the following Secondary | |
| * Licenses when the conditions for such availability set forth in the | |
| * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | |
| * version 2 with the GNU Classpath Exception, which is available at | |
| * https://www.gnu.org/software/classpath/license.html. | |
| * | |
| * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | |
| */ | |
| package versionedappclient.client; | |
| import java.io.BufferedInputStream; | |
| import java.io.File; | |
| import java.io.FileOutputStream; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.net.HttpURLConnection; | |
| import java.net.URI; | |
| import java.net.URL; | |
| import java.util.StringTokenizer; | |
| import javax.xml.parsers.DocumentBuilder; | |
| import javax.xml.parsers.DocumentBuilderFactory; | |
| import javax.xml.parsers.ParserConfigurationException; | |
| import javax.xml.xpath.XPath; | |
| import javax.xml.xpath.XPathConstants; | |
| import javax.xml.xpath.XPathExpression; | |
| import javax.xml.xpath.XPathExpressionException; | |
| import javax.xml.xpath.XPathFactory; | |
| import org.w3c.dom.Document; | |
| import org.w3c.dom.NodeList; | |
| import org.xml.sax.SAXException; | |
| /** | |
| * Retrieve and store at the given place (arg[1]) the client stubs and the application | |
| * bits of the currently enabled version of the appclient available at the given URL (arg[0]). | |
| * | |
| * This is not the real client class, this class is only used to retrieve | |
| * the stubs of the currently enabled version. This is because the | |
| * "asadmin get-client-stubs" command is not aware of the enabled state. | |
| * | |
| * This class retrieve the stubs from the JWS URL of the application. | |
| * | |
| * The GlassFish server now uses http sessions to maintain | |
| * some important information during Java Web Start launches. | |
| * For this test to work it now saves the session that is set | |
| * on the first response and sends it back on the later request which | |
| * retrieves the JAR. | |
| * | |
| * @author Romain GRECOURT - SERLI (romain.grecourt@serli.com) | |
| */ | |
| public class GetJWSClientStubs { | |
| private static final String SESSION_PROPERTY_NAME = "JSESSIONID"; | |
| String javaWebStartUrl; | |
| String stubsPath; | |
| String session = null; | |
| public GetJWSClientStubs(String[] args) { | |
| if (args.length != 2) { | |
| usage(); | |
| System.exit(1); | |
| } else { | |
| javaWebStartUrl = args[0]; | |
| stubsPath = args[1]; | |
| } | |
| } | |
| // extract the value attribute of the agent.args jnlp xml element | |
| private String extractJnlpAgentArgsValue(File xmlFile) throws ParserConfigurationException, SAXException, | |
| IOException, XPathExpressionException { | |
| String agentArgsValue = null; | |
| if (xmlFile != null && xmlFile.canRead()) { | |
| DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); | |
| domFactory.setNamespaceAware(true); // never forget this! | |
| DocumentBuilder builder = domFactory.newDocumentBuilder(); | |
| Document doc = builder.parse(xmlFile); | |
| XPathFactory factory = XPathFactory.newInstance(); | |
| XPath xpath = factory.newXPath(); | |
| XPathExpression expr = | |
| xpath.compile("//property[@name='agent.args']/@value"); | |
| Object result = expr.evaluate(doc, XPathConstants.NODESET); | |
| // retrieve the result | |
| NodeList nodes = (NodeList) result; | |
| if (nodes.getLength() == 1) { | |
| agentArgsValue = nodes.item(0).getNodeValue(); | |
| } | |
| } | |
| return agentArgsValue; | |
| } | |
| // extract the url from the value attribute of agent.args jnlp xml element | |
| private String extractAgentArgsValueUrl(String value) { | |
| String stubsUrl = null; | |
| String searchPattern = "Client.jar"; | |
| if (value != null && !value.isEmpty()) { | |
| StringTokenizer st = new StringTokenizer(value, ","); | |
| while (st.hasMoreTokens()) { | |
| String curToken = (String) st.nextElement(); | |
| if (curToken.contains(searchPattern)) { | |
| st = new StringTokenizer(curToken, "="); | |
| while (st.hasMoreElements()) { | |
| curToken = (String) st.nextElement(); | |
| if (curToken.contains(searchPattern)) { | |
| stubsUrl = curToken; | |
| break; | |
| } | |
| } | |
| break; | |
| } | |
| } | |
| } | |
| return stubsUrl; | |
| } | |
| private File get(String url, String workingDir) throws IOException { | |
| File result = null; | |
| BufferedInputStream bis = null; | |
| FileOutputStream fos = null; | |
| if (url != null && !url.isEmpty()) { | |
| try { | |
| URL u = new URI(url).normalize().toURL(); | |
| HttpURLConnection c1 = (HttpURLConnection) u.openConnection(); | |
| if (session != null) { | |
| c1.setRequestProperty( | |
| "Cookie",SESSION_PROPERTY_NAME + "=" + session); | |
| } | |
| int code = c1.getResponseCode(); | |
| if (code == 200) { | |
| final String s = getSession(c1); | |
| if (s != null) { | |
| session = s; | |
| } | |
| if (workingDir != null) { | |
| File wd = new File(workingDir); | |
| if (!wd.isDirectory()) { | |
| wd = wd.getParentFile(); | |
| } | |
| String stubsFileName = u.getPath(); | |
| stubsFileName = | |
| stubsFileName.substring(stubsFileName.lastIndexOf("/") + 1); | |
| result = new File(wd, stubsFileName); | |
| if (result.exists()) { | |
| result.delete(); | |
| } | |
| } else { | |
| result = File.createTempFile("jws", null); | |
| } | |
| InputStream is = c1.getInputStream(); | |
| bis = new BufferedInputStream(is); | |
| fos = new FileOutputStream(result); | |
| byte[] buf = new byte[256]; | |
| int readStatus; | |
| while ((readStatus = bis.read(buf)) != -1) { | |
| fos.write(buf, 0, readStatus); | |
| } | |
| } else { | |
| log("bad http code: " + code); | |
| } | |
| } catch (Exception ex) { | |
| ex.printStackTrace(); | |
| } finally { | |
| if (bis != null) { | |
| bis.close(); | |
| } | |
| if (fos != null) { | |
| fos.close(); | |
| } | |
| } | |
| } | |
| return result; | |
| } | |
| private String getSession(final HttpURLConnection c) { | |
| final String s = c.getHeaderField("Set-Cookie"); | |
| log("Set-Cookie from server is " + s); | |
| if (s == null) { | |
| return null; | |
| } | |
| for (String cookie : s.split(";")) { | |
| final int equalsSlot = cookie.indexOf("="); | |
| if (equalsSlot != -1) { | |
| return cookie.substring(equalsSlot + 1); | |
| } | |
| } return null; | |
| } | |
| private String makeJWSAppURLFromStubsURL(String stubsURL) { | |
| String globalAppURL = | |
| stubsURL.substring(0, stubsURL.lastIndexOf("/") + 1); | |
| String appclientAbsoluteName = | |
| stubsURL.substring(stubsURL.lastIndexOf("/") + 1, stubsURL.lastIndexOf(".")); | |
| String untaggedName = | |
| appclientAbsoluteName.substring(0, appclientAbsoluteName.lastIndexOf("Client")); | |
| return globalAppURL.concat(appclientAbsoluteName).concat("/").concat(untaggedName).concat(".jar"); | |
| } | |
| public void process() { | |
| try { | |
| log("trying to retrieve the jnlp file available at: " + javaWebStartUrl); | |
| // get the jnlp file available at the JWS url | |
| File jnlpFile = get(javaWebStartUrl, null); | |
| if (jnlpFile.exists()) { | |
| log("jnlp file retrieved!"); | |
| } | |
| // parse the jnlp file | |
| String agentArgsValue = extractJnlpAgentArgsValue(jnlpFile); | |
| if (agentArgsValue != null) { | |
| log("xpath request ran OK!"); | |
| // retrieve the stubs url of the currently enabled version | |
| String currentlyEnabledStubsUrl = | |
| extractAgentArgsValueUrl(agentArgsValue); | |
| if (currentlyEnabledStubsUrl != null) { | |
| log("stubs url retrieved: "+currentlyEnabledStubsUrl); | |
| // get the stubs of the currently enabled version | |
| File stubsFile = get(currentlyEnabledStubsUrl, stubsPath); | |
| if (stubsFile != null && stubsFile.canRead()) { | |
| log("clientStubs saved at: " + stubsFile.getPath()); | |
| File workingDir = new File(stubsPath); | |
| if (!workingDir.isDirectory()) { | |
| workingDir = workingDir.getParentFile(); | |
| } | |
| String stubsFileName = stubsFile.getName(); | |
| stubsFileName = | |
| stubsFileName.substring(0, stubsFileName.lastIndexOf(".jar")); | |
| File appFileDir = new File(workingDir, stubsFileName); | |
| if (appFileDir.exists()) { | |
| appFileDir.delete(); | |
| } | |
| appFileDir.mkdir(); | |
| String currentlyEnabledAppURL = | |
| makeJWSAppURLFromStubsURL(currentlyEnabledStubsUrl); | |
| File appFile = get(currentlyEnabledAppURL, appFileDir.getPath()); | |
| if (appFile != null && appFile.canRead()) { | |
| log("clientApp saved at: " + appFile.getPath()); | |
| log("return code (0): everything is OK"); | |
| System.exit(0); | |
| } | |
| } else { | |
| log("an error occured when downloading the stubs jar"); | |
| } | |
| } else { | |
| log("an error occured when trying to retrieve the stubs URL"); | |
| } | |
| } else { | |
| log("an error occured during XPATH request execution"); | |
| } | |
| } catch (Exception ex) { | |
| log(ex.getLocalizedMessage()); | |
| } | |
| log("return code (1): an error occured"); | |
| System.exit(1); | |
| } | |
| private void log(String message) { | |
| System.err.println("[versionedappclient.client.GetJWSClientStubs]:: " + message); | |
| } | |
| private void usage() { | |
| System.out.println("arg1: JavaWebStartUrl - arg2: DirPath"); | |
| } | |
| /** | |
| * @param args the command line arguments | |
| */ | |
| public static void main(String[] args) throws IOException { | |
| GetJWSClientStubs client = new GetJWSClientStubs(args); | |
| client.process(); | |
| } | |
| } |