<%@ page contentType="text/html" %> <%@ page import="java.net.*" %> <%@ page import="java.util.*" %> <%@ page import="java.util.regex.*" %> <%@ page import="java.util.zip.*" %> <%@ page import="java.io.*" %> <%@ page import="java.text.SimpleDateFormat" %> <%@ page import="org.openlaszlo.utils.FileUtils.*" %> SOLO Application Deployment Wizard <% /* We want an option to deploy an app and it's entire directory. So, for an app with is at /foo/bar/baz.lzx That should make a zip file which is relative to the web root and has /lps/includes/** /foo/bar/** -- will include the SOLO .lzx.swfN.swf file(s) /foo/bar/baz.lzx.html -- the wrapper file */ // Set this to make a limit on the size of zip file that is created int maxZipFileSize = 64000000; // 64MB max int warnZipFileSize = 10000000; // warn at 10MB boolean warned = false; String zipfilename = ""; String whatpage = request.getParameter("whatpage"); if (whatpage == null) { whatpage = "configure"; } String appUrl = request.getParameter("appurl"); if (appUrl == null) { appUrl = ""; } appUrl = appUrl.trim(); // Get the application target runtime, default to swf8 String appRuntime = request.getParameter("runtime"); if (appRuntime == null) { appRuntime = "swf8"; } String title = request.getParameter("apptitle"); if (title == null) { title = ""; } URL wrapperUrl = null; URL lzhistUrl = null; String appwidth = request.getParameter("appwidth"); String appheight = request.getParameter("appheight"); // Get app width/height from its canvas wrapper // download text content of URL StringBuffer wrapperbuf = new StringBuffer(); StringBuffer lzhistbuf = new StringBuffer(); String lzhistwrapper = ""; /* request.getContextPath(): /lps-dev request.getRequestURI(): /lps-dev/hqm/test/solo-deploy.jsp request.getRequestURL(): http://localhost:8080/lps-dev/hqm/test/solo-deploy.jsp request.getServletPath(): /hqm/test/solo-deploy.jsp */ String sUrl = request.getRequestURL().toString(); String servletPath = request.getServletPath(); String baseUrl = sUrl.substring(0, (sUrl.length() - servletPath.length())+1); if (appUrl != null && appUrl.length() > 0) { // remove dangerous pathname components, "..", and "//" if (appUrl.indexOf("..") != -1 || appUrl.indexOf("//") != -1) { %>

Error, do not use '..' or '//' in your app pathname: <%= appUrl %>

<% } try { // okee dokee. Now we have to adjust the app path to be relative to // the server document root. // say that appUrl == demos/vacation-survey/vacation-survey.lzx // trim leading slash if (appUrl.charAt(0) == '/') { appUrl = appUrl.substring(1); } // If there are no "/" separators in the non-zero position in the // url string , then the app url is at the LPS_HOME root, and that // is bad thing to try to zip up recursively, so issue a warning // and refuse to do it. if (appUrl.indexOf("/") == -1) { %>

Error bad location for app file

You entered <%= appUrl %>, which names a file in the server document root directory. Please place the file in a subdirectory of the server root directory and try again with the new path.

Explanation: The SOLO deployment tool creates an archive of all files, recursively, starting in the directory that contains the application source file. If the application source file is in the servlet root container, this tool will create a zip that contains all the files inside the root directory. This directory contains the entire OpenLaszlo binary distribution, so this is almost certainly not what you want. <% return; } wrapperUrl = new URL(new URL(baseUrl), appUrl + "?lzt=html-object&lzproxied=false&lzr="+appRuntime); lzhistUrl = new URL(new URL(baseUrl), appUrl + "?lzt=html&lzproxied=false&lzr="+appRuntime); URL swfUrl = new URL(new URL(baseUrl), appUrl + "?lzr="+appRuntime+"&lzproxied=false"); // Grab a copy of the html-object wrapper String str; BufferedReader in = new BufferedReader(new InputStreamReader(wrapperUrl.openStream())); while ((str = in.readLine()) != null) { wrapperbuf.append(str+"\n"); } in.close(); // load a copy of the lzhistory HTML wrapper in = new BufferedReader(new InputStreamReader(lzhistUrl.openStream())); while ((str = in.readLine()) != null) { lzhistbuf.append(str+"\n"); } in.close(); // Load a copy of the app url , causing the compiler to run in = new BufferedReader(new InputStreamReader(swfUrl.openStream())); while ((str = in.readLine()) != null) { } in.close(); lzhistwrapper = lzhistbuf.toString(); // We need to adjust the lzhistory wrapper, to make the path to lps/includes/embed.js // be relative rather than absolute. // remove the servlet prefix and leading slash lzhistwrapper = lzhistwrapper.replaceAll(request.getContextPath()+"/", ""); lzhistwrapper = lzhistwrapper.replaceAll(request.getContextPath(), ""); lzhistwrapper = lzhistwrapper.replaceAll("[.]lzx[?]lzt=swf", ".lzx."+appRuntime+".swf?"); } catch (MalformedURLException e) { %>

Error retrieving URL <%= appUrl %>: <%= e.toString() %>

<% } catch (IOException e) { %>

Error retrieving URL <%= appUrl %>: <%= e.toString() %>

<% } } else { appUrl = "examples/animation/animation.lzx"; } String wrapper = wrapperbuf.toString(); // replace title wrapper = wrapper.replaceFirst(".*", ""+title+"\n"); // extract width and height with regexp Pattern pwidth = Pattern.compile("width=\"([0-9]*)\""); Pattern pheight = Pattern.compile("height=\"([0-9]*)\""); Matcher mwidth = pwidth.matcher(wrapper); Matcher mheight = pheight.matcher(wrapper); if (mwidth.find()) { appwidth = mwidth.group(1); } else { appwidth = "640"; } if (mheight.find()) { appheight = mheight.group(1); } else { appheight = "400"; } int nwidth = 640; int nheight = 400; try { nwidth = Integer.parseInt(appwidth); nheight = Integer.parseInt(appheight); } catch (Exception e) { out.println(e.toString()); } // if no form vars, we are at page #0 if (whatpage.equals("configure")) { %> Setup SOLO Application Deployment

This wizard will generate a zip file containing all the resources you need to deploy a serverless (SOLO) application. For deployments which do not require browser the Javscript browser integration support files, it will also generate some simple HTML wrappers which can be cut and pasted into HTML pages.
Use a pathname relative to the LPS server root, e.g. if the LPS server is mapped to http://localhost:8080/lps, and your application is accessed at http://localhost:8080/lps/examples/animation/animation.lzx then enter examples/animation/animation.lzx
Enter pathname of your application:
Title for web page:

<% } else if (whatpage.equals("preview")){ %> Preview SOLO Application in Browser


<% String soloURL = (request.getContextPath()+"/" + appUrl + "."+appRuntime+".swf?lzproxied=false"); %> Using URL <%= soloURL %>

Size = <%= appwidth %> x <%= appheight %>

OK, give me the HTML wrapper code

Go back to change

<% } else if (whatpage.equals("download")){ %> <% String htmlfile = ""; // add in all the files in the app directory ServletContext ctx = getServletContext(); // destination to output the zip file, will be the current jsp directory File tmpdir = new File(ctx.getRealPath(request.getServletPath().toString())).getParentFile(); // The absolute path to the base directory of the server web root File basedir = new File(ctx.getRealPath(request.getContextPath().toString())).getParentFile(); // The absolute path to the application directory we are packaging // e.g., demos/amazon File appdir = new File(ctx.getRealPath(appUrl)).getParentFile(); // Keep track of which files we have output to the zip archive, so we don't // write any duplicate entries. HashSet zippedfiles = new HashSet(); // These are the files to include in the ZIP file ArrayList filenames = new ArrayList(); // LPS includes, (originally copied from /lps/includes/*) filenames.add("lps/includes/embed-compressed.js"); ArrayList appfiles = new ArrayList(); listFiles(appfiles, appdir); // Create a buffer for reading the files byte[] buf = new byte[1024]; char[] cbuf = new char[1024]; try { // Create the ZIP file SimpleDateFormat format = new SimpleDateFormat("MMM_dd_yyyy_HH_mm_ss"); String outFilename = "solo_deploy_" + format.format(new Date()) + ".zip"; zipfilename = outFilename; ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(tmpdir+"/"+outFilename)); // create a byte array from lzhistory wrapper text htmlfile = new File(appUrl).getName()+".html"; byte lbytes[] = lzhistwrapper.getBytes(); copyByteArrayToZipFile(zout, lbytes, htmlfile, zippedfiles); // Compress the include files for (int i=0; i maxZipFileSize) { throw new IOException("file length exceeds max of "+ (maxZipFileSize/1000000) +"MB"); } if (contentSize > warnZipFileSize && !warned) { warned = true; %>

The zip file has had more than <%= warnZipFileSize / 1000000 %>MB of content added to it, perhaps this is what you intended, but remember that the SOLO deployment tool creates an archive of all files, recursively, from the directory that contains your specified application source file. If your application source file is in a directory with other apps, this tool will create a zip that contains all those apps and their assets (and subdirectories) as well.

<% } } // Complete the ZIP file zout.close(); } catch (IOException e) { %>

Error generating zip file: <%= e.toString() %>

<% } %> Zip file containing application deployment files

Click here to download zip-archived file <%=zipfilename%>.

In the zip file, a wrapper HTML file named <%= htmlfile %> has been created to launch your SOLO application.

Note: the file may take a moment to generate and save to disk, please be patient.

SOLO Application Deployment: Wrapper HTML


Paste this wrapper into a browser to deploy your app:

Browser History/Integration Wrapper HTML


Paste this wrapper into a browser to deploy your app:

HTML code to pop up a new window with the app


<% } %> <%! // utility methods public void listFiles(ArrayList fnames, File dir) { if (dir.isDirectory()) { if (!(dir.getName().startsWith(".svn"))) { String[] children = dir.list(); for (int i=0; i 0) { zout.write(buf, 0, len); } // Complete the entry zout.closeEntry(); in.close(); zipped.add(dstfixed); } public String fixSlashes (String path) { return(path.replace('\\', '/')); } %>