/* * eXist Open Source Native XML Database * Copyright (C) 2001-06 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * $Id$ */ package org.exist.webstart; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; /** * Class for writing JNLP file, jar files and image files. * * @author Dannes Wessels */ public class JnlpWriter { private static final String JAR_MIME_TYPE = "application/x-java-archive"; public static final String ACCEPT_ENCODING = "accept-encoding"; public static final String CONTENT_TYPE = "content-type"; public static final String CONTENT_ENCODING = "content-encoding"; public static final String PACK200_GZIP_ENCODING = "pack200-gzip"; private static Logger logger = Logger.getLogger(JnlpWriter.class); /** * Write JNLP files (jnlp, jar, gif/jpg) to browser. * @param response Object for writing to end user. * @throws java.io.IOException */ void writeJnlpXML(JnlpJarFiles jnlpFiles, HttpServletRequest request, HttpServletResponse response) throws IOException { logger.debug("Writing JNLP file"); // Format URL: "http://host:8080/CONTEXT/webstart/exist.jnlp" String currentUrl = request.getRequestURL().toString(); // Find BaseUrl http://host:8080/CONTEXT int webstartPos = currentUrl.indexOf("/webstart"); String existBaseUrl = currentUrl.substring(0, webstartPos); // Find codeBase for jarfiles http://host:8080/CONTEXT/webstart/ String codeBase = existBaseUrl+"/webstart/"; // Perfom sanity checks File mainJar=jnlpFiles.getMainJar(); if(mainJar==null || !mainJar.exists()){ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Missing exist.jar !"); return; } File coreJars[] = jnlpFiles.getCoreJars(); for(int i=0 ; i<coreJars.length ; i++) { if(coreJars[i]==null || !coreJars[i].exists()){ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Missing Jar file! ("+i+")"); return; } } // Find URL to connect to with client String startUrl = existBaseUrl .replaceFirst("http:", "xmldb:exist:") .replaceAll("-", "%2D") + "/xmlrpc"; response.setDateHeader("Last-Modified", mainJar.lastModified()); response.setContentType("application/x-java-jnlp-file"); PrintWriter out = response.getWriter(); out.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); out.println("<jnlp spec=\"1.0+\" codebase=\"" + codeBase + "\" href=\"exist.jnlp\">" ); out.println("<information>"); out.println(" <title>eXist XML-DB client</title>"); out.println(" <vendor>exist-db.org</vendor>"); out.println(" <homepage href=\"http://exist-db.org/\"/>"); out.println(" <description>Integrated command-line and gui client, "+ "entirely based on the XML:DB API and provides commands "+ "for most database related tasks, like creating and "+ "removing collections, user management, batch-loading "+ "XML data or querying.</description>"); out.println(" <description kind=\"short\">eXist XML-DB client</description>"); out.println(" <description kind=\"tooltip\">eXist XML-DB client</description>"); out.println(" <icon href=\"jnlp_logo.jpg\" kind=\"splash\"/>"); out.println(" <icon href=\"jnlp_logo.jpg\" />"); out.println(" <icon href=\"jnlp_icon_64x64.gif\" width=\"64\" height=\"64\" />"); out.println(" <icon href=\"jnlp_icon_32x32.gif\" width=\"32\" height=\"32\" />"); out.println("</information>"); out.println("<security>"); out.println(" <all-permissions />"); out.println("</security>"); out.println("<resources>"); out.println("<j2se version=\"1.5+\"/>"); out.println(" <jar href=\"" + jnlpFiles.getMainJar().getName() +"\" size=\""+ jnlpFiles.getMainJar().length() + "\" main=\"true\" />"); for(int i=0 ; i<coreJars.length ; i++) { out.println(" <jar href=\"" + coreJars[i].getName() + "\" size=\""+ coreJars[i].length() +"\" />"); } out.println("</resources>"); out.println("<application-desc main-class=\"org.exist.client.InteractiveClient\">"); out.println(" <argument>-ouri=" + startUrl + "</argument>"); out.println(" <argument>--no-embedded-mode</argument>"); out.println("</application-desc>"); out.println("</jnlp>"); out.flush(); out.close(); } /** * Send JAR file to end user. * @param filename Name of JAR file * @param response Object for writing to end user. * @throws java.io.IOException */ void sendJar(JnlpJarFiles jnlpFiles, String filename, HttpServletRequest request, HttpServletResponse response ) throws IOException { logger.debug("Send jar file "+ filename); File localJarFile = jnlpFiles.getFile(filename); if(localJarFile==null || !localJarFile.exists()){ response.sendError(HttpServletResponse.SC_NOT_FOUND, "Jar file '"+filename+"' not found."); return; } String localJarPath = localJarFile.getAbsolutePath(); // Retrieve info from client String acceptedEncoding = request.getHeader(ACCEPT_ENCODING); if(acceptedEncoding==null){ acceptedEncoding=""; } String contentType=JAR_MIME_TYPE; File downloadTarget=null; File localPackedFile=new File(localJarPath + ".pack.gz"); if(acceptedEncoding.indexOf(PACK200_GZIP_ENCODING)!=-1 && localPackedFile.exists() && localPackedFile.canRead() ){ downloadTarget = localPackedFile; response.setHeader(CONTENT_ENCODING, PACK200_GZIP_ENCODING); } else { downloadTarget=localJarFile; } logger.debug("Actual file "+downloadTarget.getAbsolutePath()); response.setContentType(contentType); response.setContentLength( Integer.parseInt(Long.toString(downloadTarget.length())) ); response.setDateHeader("Last-Modified",downloadTarget.lastModified()); FileInputStream fis = new FileInputStream( downloadTarget ); ServletOutputStream os = response.getOutputStream(); try { // Transfer bytes from in to out byte[] buf = new byte[4096]; int len; while ((len = fis.read(buf)) > 0) { os.write(buf, 0, len); } } catch (IllegalStateException ex){ logger.debug(ex.getMessage()); } catch (IOException ex){ logger.debug("Ignore IOException for '" + filename + "'"); } os.flush(); os.close(); fis.close(); } void sendImage(JnlpHelper jh, JnlpJarFiles jf, String filename, HttpServletResponse response) throws IOException { logger.debug("Send image "+ filename); File imagesFolder = new File(jh.getWebappFolder() , "resources"); String type=null; if(filename.endsWith(".gif")){ type="image/gif"; } else { type="image/jpeg"; } response.setContentType(type); File imageFile = new File(imagesFolder, filename); if(imageFile==null || !imageFile.exists()){ response.sendError(HttpServletResponse.SC_NOT_FOUND, "Image file '"+filename+"' not found."); return; } response.setContentLength( Integer.parseInt(Long.toString(imageFile.length())) ); response.setDateHeader("Last-Modified",imageFile.lastModified()); FileInputStream fis = new FileInputStream( imageFile ); ServletOutputStream os = response.getOutputStream(); try { // Transfer bytes from in to out byte[] buf = new byte[8096]; int len; while ((len = fis.read(buf)) > 0) { os.write(buf, 0, len); } } catch (IllegalStateException ex){ logger.debug(ex.getMessage()); } catch (IOException ex){ logger.debug("Ignore IOException for '" + filename + "'"); } os.flush(); os.close(); fis.close(); } }