Package com.adito.agent.client.util

Source Code of com.adito.agent.client.util.AbstractApplicationLauncher

        /*
*  Adito
*
*  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.adito.agent.client.util;

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.io.StringReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.zip.Adler32;
import java.util.zip.CheckedInputStream;

import com.adito.agent.client.util.types.DefaultAgentApplicationType;
import com.adito.agent.client.util.types.ExecutableApplicationType;
import com.adito.agent.client.util.types.HtmlApplicationType;
import com.adito.agent.client.util.types.JavaApplicationType;

/**
* Launches an application shortcut by downloading the extension descriptor for
* the appropriate application extension, processing it then launching the
* application.
* <p>
* During processing of the descriptor, additional files may be download and
* cached on the client.
* <p>
* How the application is launched depends on its type. Types include
* {@link JavaApplicationType}, {@link DefaultAgentApplicationType},
* {@link HtmlApplicationType}, {@link ExecutableApplicationType}.
*/
public abstract class AbstractApplicationLauncher {

  static Vector EMPTY_VECTOR = new Vector();
    File installDir;
    File sharedDir;
    String typeName;

    String name;
    String ticket;

    //  Protected instance variables
   
    protected String applicationStoreProtocol;
    protected String applicationStoreHost;
    protected String applicationStoreUser;
    protected int applicationStorePort;
    protected ApplicationLauncherEvents events;
    protected Hashtable parameters;
   
    // Privaet instance variables

    private long totalBytesToDownload = 0;
    private Vector filesToDownload = new Vector();
    private Hashtable sharedFilesToDowload = new Hashtable();
    private Hashtable descriptorParams = new Hashtable();
    private boolean debug = false;
    private String localProxyURL;
    private ApplicationType type;
    private Hashtable replacements = new Hashtable();
    private Vector transformations = new Vector();
    private boolean hasPrepared = false;
    private File cacheDir;
    private String smallIcon, largeIcon;
   
    /**
     * Constructor.
     *
     * @param cacheDir cache directory
     * @param applicationStoreProtocol application store protocol (http / https)
     * @param applicationStoreUser application store userinfo (CHECK user /
     *        password or ticket?)
     * @param applicationStoreHost application store host
     * @param applicationStorePort application store port
     * @param parameters parmaeters
     * @param events callback interface for events
     */
    public AbstractApplicationLauncher(File cacheDir, String applicationStoreProtocol, String applicationStoreUser, String applicationStoreHost,
                               int applicationStorePort, Hashtable parameters, ApplicationLauncherEvents events) {
        this.cacheDir = cacheDir;
        this.applicationStoreProtocol = applicationStoreProtocol;
        this.applicationStoreHost = applicationStoreHost;
        this.applicationStoreUser = applicationStoreUser;
        this.applicationStorePort = applicationStorePort;
        this.parameters = parameters;
        this.events = events;
    }

    /**
     * Set the URL of the local proxy server (if required). This is used when
     * replacing variables in the extension descriptor.
     *
     * @param localProxyURL local proxy URL
     */
    public void setLocalProxyURL(String localProxyURL) {
        this.localProxyURL = localProxyURL;
    }

    /**
     * If set to true, a <b>debug</b> property with be added to parameters.
     *
     * @param debug send debug parameter
     */
    public void setDebug(boolean debug) {
        this.debug = debug;
    }
   
    /**
     * Is the application in debug mode?
     * @return
     */
    public boolean isDebug() {
      return debug;
    }

    /**
     * Get the application type implementation.
     *
     * @return application type
     */
    public ApplicationType getApplicationType() {
        return type;
    }

    /**
     * Prepare and download and process the extension descriptor.
     *
     * @throws IOException on any error
     */
    public void prepare() throws IOException {

      hasPrepared = true;
     
        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.checkingParameters")); //$NON-NLS-1$

        // Add a debug parameter if were debugging
        if (debug) {
            parameters.put("debug", "true"); //$NON-NLS-1$ //$NON-NLS-2$
        }

        ticket = (String) parameters.get("ticket"); //$NON-NLS-1$
        if (events != null && ticket!=null)
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.storingTicket"), new Object[] { ticket })); //$NON-NLS-1$

        XMLElement element = new XMLElement();
       
        // Read the XML into a string first so it can be displayed upon exception

        events.debug(Messages.getString("ApplicationLauncher.gettingDescriptorStream")); //$NON-NLS-1$
        InputStreamReader reader = new InputStreamReader(getApplicationDescriptor());
        events.debug(Messages.getString("ApplicationLauncher.readingDescriptorStream")); //$NON-NLS-1$
        char[] cbuf = new char[65536];
        StringBuffer xml = new StringBuffer();
        int read = 0;
        while (read != -1) {
          read = reader.read(cbuf,0,cbuf.length);
          if(read != -1) {
                events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.readBlock"), new Object[] { String.valueOf(read) })); //$NON-NLS-1$
                xml.append(cbuf,0,read);
          }
        }
        try {
            events.debug(Messages.getString("ApplicationLauncher.parsingDescriptor")); //$NON-NLS-1$
          element.parseFromReader(new StringReader(xml.toString()));
            events.debug(Messages.getString("ApplicationLauncher.parsedDescriptor")); //$NON-NLS-1$
        }
        catch(XMLParseException xmlpe) {
            if (events != null) {
                events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.failedToParseXML"), new Object[] { xmlpe.getMessage() } ) ); //$NON-NLS-1$
                events.debug(xml.toString());
            }
            throw xmlpe;
        }
       
        if(debug)
          events.debug("[XML] [" + xml.toString() + "]");

        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.receivedResponseFromServer")); //$NON-NLS-1$

        if (!element.getName().equals("application") && !element.getName().equals("error") //$NON-NLS-1$ //$NON-NLS-2$
            && !element.getName().equals("extension")) { //$NON-NLS-1$
            throw new IOException(Messages.getString("ApplicationLauncher.urlDoesNotPointToApplicationDescriptor")); //$NON-NLS-1$
        } else if (element.getName().equals("error")) { //$NON-NLS-1$
            throw new IOException(element.getContent());
        }

        name = (String) element.getAttribute("extension"); //$NON-NLS-1$
        if (name == null) {
            name = (String) element.getAttribute("application"); //$NON-NLS-1$
        }

        typeName = (String) element.getAttribute("type"); //$NON-NLS-1$
        smallIcon = (String) element.getAttribute("smallIcon"); //$NON-NLS-1$
        largeIcon = (String) element.getAttribute("largeIcon"); //$NON-NLS-1$
       
        try {
           type = ApplicationTypeManager.getInstance().createType(typeName);
        } catch (Throwable t) {
          t.printStackTrace();
            throw new IOException(MessageFormat.format(Messages.getString("ApplicationLauncher.failedToLoadApplicationDescriptor"), new Object[] { typeName + " " + t.getMessage() })); //$NON-NLS-1$
        }

        if (events != null)
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.applicationNameIs"), new Object[] { name, type.getClass().getName() })); //$NON-NLS-1$

        if (events != null) {
            events.processingDescriptor();
        }

        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.creatingInstallFolder")); //$NON-NLS-1$

        // This code attempts to detect the MSJVM and obtain the users profile
        // directory so that it can be used as the users home.

        if (events != null)
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.userHomeIs"), new Object[] { cacheDir.getAbsolutePath() })); //$NON-NLS-1$

        installDir = new File(cacheDir, "applications" + File.separator + name); //$NON-NLS-1$ //$NON-NLS-2$

        sharedDir = new File(cacheDir, "shared"); //$NON-NLS-1$ //$NON-NLS-2$

        if (!installDir.exists()) {
            installDir.mkdirs();
        }

        if (!sharedDir.exists()) {
            sharedDir.mkdirs();
        }

        if (events != null)
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.installingTo"), new Object[] { installDir.getAbsolutePath() })); //$NON-NLS-1$

       
        processElements(element);
       
    }
   
    void processElements(XMLElement element) throws IOException {
       
      Enumeration e = element.enumerateChildren();
     
      while (e.hasMoreElements()) {
            XMLElement el = (XMLElement) e.nextElement();

            if(el.getName().equalsIgnoreCase("if")) {
              // This catch all if allows <if> at top level of all elements.
              // WARNING: do not use lightly!!
              if(checkCondition(type, el, parameters)) {
                   processElements(el)
              }
            } else if (el.getName().equalsIgnoreCase("files")) { //$NON-NLS-1$
                processFiles(el);
            } else if (el.getName().equalsIgnoreCase("tunnel")) { //$NON-NLS-1$
                // This should contain the host and port of a tunnel that
                // we need to create
                createTunnel(el);
            } else if (el.getName().equalsIgnoreCase("parameter")) { //$NON-NLS-1$
                addParameter(el);
            } else if (el.getName().equalsIgnoreCase("messages")) { //$NON-NLS-1$
                // Ignore as its a server side element
            } else if (el.getName().equalsIgnoreCase("description")) { //$NON-NLS-1$
                // Simply ignore.. should we throw an exception if an element is
                // not known?
            } else if (el.getName().equalsIgnoreCase("replacements")) { //$NON-NLS-1$
                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")) { //$NON-NLS-1$
                ParameterTransformation trans = new ParameterTransformation(el, this);
                transformations.addElement(trans);
            } else {
                type.prepare(this, events, el);
            }
        }     
    }
   
    public void download() throws IOException {
     
      downloadFiles();

        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.applyingParameterTransformations")); //$NON-NLS-1$

        for (Enumeration ep = transformations.elements(); ep.hasMoreElements();) {
            ParameterTransformation trans = (ParameterTransformation) ep.nextElement();
            trans.processTransformation();
        }

        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.creatingReplacements")); //$NON-NLS-1$

        for (Enumeration ep = replacements.elements(); ep.hasMoreElements();) {
            FileReplacement replacement = (FileReplacement) ep.nextElement();
            replacement.createReplacementsFile(this);
        }

        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.replacementsCreatedPreparationComplete")); //$NON-NLS-1$     
    }
   
    /**
     * Get the name of the small icon for this application.
     *
     * @return small icon
     */
    public String getSmallIcon() {
      return smallIcon;
    }
   
    /**
     * Get the name of the large icon for this application.
     *
     * @return small icon
     */
    public String getLargeIcon() {
      return largeIcon;
    }

    /**
     * Download the application descriptor. This should not be called directory,
     * it gets called during {@link #prepare()}.
     *
     * @return application descriptor stream
     * @throws IOException
     */
    protected abstract InputStream getApplicationDescriptor() throws IOException;

    protected boolean processLauncherElement(XMLElement e) {
        return false;
    }

    /**
     * Get the application name
     *
     * @return application name
     */
    public String getName() {
        return name;
    }

    /**
     * Get the directory where the applications files will be installed.
     *
     * @return install directory
     */
    public File getInstallDir() {
        return installDir;
    }

    /**
     * Start the application
     */
    public void start() throws IOException {
      download();
        type.start();
    }

    /**
     * Add a new parameter to the launcher. This must be done before the
     * application is launched.
     *
     * @param parameter
     * @param value
     */
    public void addParameter(String parameter, String value) {

        if (events != null) {
            if (parameter == "password"){
                events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.addingParameter"), new Object[] { parameter, "**********" }));//$NON-NLS-1$
            }
            else{
                events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.addingParameter"), new Object[] { parameter, value }));//$NON-NLS-1$
            }
        }

        descriptorParams.put(parameter, value);
    }

    /**
     * Process the application extension descriptor.
     *
     * @param element XML element
     * @throws IOException
     */
    public void processFiles(XMLElement element) throws IOException {
        processFiles(element, null);
    }

    /**
     * Process the application extension descriptor.
     *
     * @param element XML element
     * @param app application
     * @throws IOException
     */
    public void processFiles(XMLElement element, String app) throws IOException {

        Enumeration en = element.enumerateChildren();
        XMLElement e;

        while (en.hasMoreElements()) {
            e = (XMLElement) en.nextElement();
            if (e.getName().equalsIgnoreCase("file")) { //$NON-NLS-1$
              if(checkCondition(type, e, parameters)) {
                    addFile(e, app);               
              }
            } else if (e.getName().equalsIgnoreCase("if")) { //$NON-NLS-1$
                if (checkCondition(type, e, parameters)) {                 
                    processFiles(e, app);
                }

            } else
                throw new IOException(MessageFormat.format(Messages.getString("ApplicationLauncher.invalidElementInFiles"), new Object[] { e.getName() }));//$NON-NLS-1$ //$NON-NLS-2$
        }

    }

    /**
     * Check for the conditions of elements to make sure they are appropriate
     * for the current platform / environment.
     * <p>
     * Only files that are ok will be downloaded / synchornized
     *
     * @param el file element
     * @return ok for use
     * @throws IOException
     * @throws IllegalArgumentException
     */
    public static boolean checkCondition(ApplicationType type, XMLElement el, Hashtable params) throws IOException, IllegalArgumentException {
      String jre = (String) el.getAttribute("jre"); //$NON-NLS-1$
      String os = (String) el.getAttribute("os"); //$NON-NLS-1$
      String osVersion = (String) el.getAttribute("osversion"); //$NON-NLS-1$
      String arch = (String) el.getAttribute("arch"); //$NON-NLS-1$
        String parameter = (String) el.getAttribute("parameter"); //$NON-NLS-1$
        String string = (String) el.getAttribute("string"); //$NON-NLS-1$
      if(jre != null) {
      if(!Utils.isSupportedJRE(jre)) {
        return false;
      }
      }
      if(os != null) {
      if(!Utils.isSupportedPlatform(os)) {
        return false;
      }
      }
      if(osVersion != null) {
      if(!Utils.isSupportedOSVersion(osVersion)) {
        return false;
      }
      }
      if(arch != null) {
      if(!Utils.isSupportedArch(arch)) {
        return false;
      }
      }
        if (parameter != null) {
          if(params == null) {
            throw new IOException(Messages.getString("ApplicationLauncher.noParametersToTestAgainst")); //$NON-NLS-1$
          }
            String requiredValue = (String) el.getAttribute("value"); //$NON-NLS-1$
            boolean not = "true".equalsIgnoreCase(((String) el.getAttribute("not"))); //$NON-NLS-1$ //$NON-NLS-2$

            // Check the parameter
            String paramValue = (String) params.get(parameter);

            if ((!not && !requiredValue.equalsIgnoreCase(paramValue)) || (not && requiredValue.equalsIgnoreCase(paramValue))) {
              return false;
            }
        }
        if(string != null) {
            String requiredValue = (String) el.getAttribute("value"); //$NON-NLS-1$
            boolean not = "true".equalsIgnoreCase(((String) el.getAttribute("not"))); //$NON-NLS-1$ //$NON-NLS-2$
           
            if ((!not && !requiredValue.equalsIgnoreCase(string)) || (not && requiredValue.equalsIgnoreCase(string))) {
              return false;
            }
        }
      return true;
    }

    /**
     * Get the application extentsion descriptor parameters as a hastable of
     * string objects
     *
     * @return descriptor parameters
     */
    public Hashtable getDescriptorParams() {
        return descriptorParams;
    }

    /**
     * Add shared file element.
     *
     * @param e shared file element
     * @return file
     * @throws IOException
     */
    public File addShared(XMLElement e) throws IOException {
        return addShared(e, null);
    }

    /**
     * Add shared file element.
     *
     * @param e shared file element
     * @param app application
     * @return file
     * @throws IOException
     */
    public File addShared(XMLElement e, String app) throws IOException {
        return addFile(e, app, true);

    }

    /**
     * Add a file.
     *
     * @param e file element
     * @param app application
     * @return file
     * @throws IOException
     */
    public File addFile(XMLElement e, String app) throws IOException {
      return addFile(e, app, false);
    }

    /**
     * Add a file.
     *
     * @param e file element
     * @param app application
     * @param fileMap file map
     * @return file
     * @throws IOException
     */
    File addFile(XMLElement e, String app, boolean shared) throws IOException {

        boolean executable = "true".equals(e.getStringAttribute("exec", "false"));
        boolean readOnly = "true".equals(e.getStringAttribute("readOnly", "false"));
        String targetDirName = e.getStringAttribute("targetDir");
       

        /**
         * LDP - Make sure any downloaded files are using the correct seperator
         * char for the platform.
         */
        String name = e.getStringAttribute("name", "");
        if(name.equals("")) {
          name = Utils.trimmedBothOrBlank(e.getContent());
        }
        name = name.replace('/', File.separatorChar);
       
        // Work out the target file
        File targetDir = installDir;
        File entry = new File(installDir, name);
        if(!Utils.isNullOrTrimmedBlank(targetDirName)) {
          if(shared) {
            throw new IOException("Cannot specify target directory for shared files.");
          }
          targetDir = new File(installDir, targetDirName);
          String filename = name;
          int idx = name.lastIndexOf(File.separatorChar);
          if(idx != -1) {
            filename = filename.substring(idx + 1);
          }
          entry = new File(targetDir, filename);
            if (events != null) {
                events.debug("Alternative target directory of " + targetDirName + " (" + targetDir.getAbsolutePath() + ") provided. Target is " + entry.getAbsolutePath());
            }
        }
       
        DownloadableFile df = new DownloadableFile(name, app, executable, readOnly, entry, 0);
        long size = 0;
        try {
          size = Long.parseLong((String) e.getAttribute("size")); //$NON-NLS-1$
        }
        catch(NumberFormatException nfe) {
            throw new IOException(MessageFormat.format(Messages.getString("ApplicationLauncher.invalidSize"), new Object[] { name })); //$NON-NLS-1$
         
        }
       
        if (events != null) {
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.addingFile"), new Object[] { entry.getAbsolutePath(), new Long(size) } )  ); //$NON-NLS-1$
        }

        boolean download = true;
       
        if (e.getAttribute("checksum") == null || e.getAttribute("size") == null) { //$NON-NLS-1$ //$NON-NLS-2$
            df.setChecksum(0);
        } else {
          df.setChecksum(Long.parseLong((String) e.getAttribute("checksum")));
        }
       
        if (entry.exists()) {

            // The file exists so lets check its size and checksum to determine
            // whether we need to download it again$

            long currentChecksum = generateChecksum(entry);

            if (events != null) {
                events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.fileExistsCurrentChecksum"), new Object[] { new Long(currentChecksum), new Long(df.getChecksum()) })); //$NON-NLS-1$ //$NON-NLS-2$
            }

            if (currentChecksum != df.getChecksum() || entry.length() != size) {
                if (events != null) {
                    events.debug(Messages.getString("ApplicationLauncher.checksumMismatchDownloading")); //$NON-NLS-1$
                }

                if(shared)
                  sharedFilesToDowload.put(name, df);
                else
                  filesToDownload.addElement(df);
               
                totalBytesToDownload += entry.length();
            }
        } else {
            if (events != null) {
                events.debug(Messages.getString("ApplicationLauncher.fileDoesntExistDownloading")); //$NON-NLS-1$
            }

            // We currently do not have the file so add it to the download list
            if(shared)
              sharedFilesToDowload.put(name, df);
            else
              filesToDownload.addElement(df);
            totalBytesToDownload += size;
        }
       
        // Add aliases
        Enumeration ae = e.enumerateChildren();
        while (ae.hasMoreElements()) {
            XMLElement el = (XMLElement) ae.nextElement();
            if(el.getName().equals("alias")) {
              df.addAlias(Utils.trimmedBothOrBlank(el.getContent()));
            }
        }

        return entry;
    }

    /**
     * Download a single file from an application extension.
     *
     * @param basedir directory to install to
     * @param app application extension id
     * @param filename filename to download
     * @param target file to download to
     * @param bytesSoFar value to start byte count at, this value will be added
     *        to then returned
     * @param executable make executable
     * @param readOnly make read only
     * @param aliases aliases
     * @return bytes read so far
     * @throws IOException on any error
     */
    public long downloadFile(File basedir, String app, String filename, File target, long bytesSoFar, boolean executable, boolean readOnly, Vector aliases, long checksum) throws IOException {

        /**
         * LDP - Another method that delegates collection of a HTTP request to a
         * seperate method so that it can be overidden.
         */
        if (events != null)
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.downloading"), new Object[] { filename, target.getAbsolutePath() })); //$NON-NLS-1$ //$NON-NLS-2$

        File f = new File(target.getParent());
        f.mkdirs();

        if (events != null)
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.creating"), new Object[] { target.getAbsolutePath() })); //$NON-NLS-1$

        target.delete();
        FileOutputStream out = new FileOutputStream(target);
        InputStream in = getDownloadFile(app, ticket, filename);
        byte[] buf = new byte[16384];
        int read;
        while ((read = in.read(buf)) > -1) {
            out.write(buf, 0, read);
            bytesSoFar += read;

            if (events != null)
                events.progressedDownload(bytesSoFar);
        }
        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.finishingDownloadFile")); //$NON-NLS-1$

        in.close();
        out.close();
       
        if(executable) {
          try {
                if (events != null)
                    events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.makingExecutable"), new Object[] { target.getPath() } ) ); //$NON-NLS-1$
            Utils.makeExecutable(target);
          }
          catch(IOException ioe) {
                if (events != null)
                    events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.failedToMakeExecutable"), new Object[] { target.getPath(), ioe.getMessage() } ) ); //$NON-NLS-1$           
          }
        }
       
        long newChecksum = generateChecksum(target);
        if(newChecksum != checksum) {
          events.debug("WARNING. File " + target.getPath() + " does not match expected checksum. Checksum is " + newChecksum + ", should be " + checksum);
        }
       
        if(readOnly) {
          try {
                if (events != null)
                    events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.makingReadOnly"), new Object[] { target.getPath() } ) ); //$NON-NLS-1$
            Utils.makeReadOnly(target);
          }
          catch(IOException ioe) {
                if (events != null)
                    events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.failedToMakeReadOnly"), new Object[] { target.getPath(), ioe.getMessage() } ) ); //$NON-NLS-1$           
          }
        }
       
        if(aliases != null && aliases.size() >0) {
          for(Enumeration e = aliases.elements(); e.hasMoreElements(); ) {
            String alias = (String)e.nextElement();
            // Copy for now, look into how to link
          File aliasTarget = new File(basedir, alias);
            if(events != null) {
              events.debug("Copying " + target.getPath() + " to " + aliasTarget.getPath());
            }
            Utils.copyFile(target, aliasTarget);
          }
        }

        return bytesSoFar;

    }

    /**
     * Get the hostname on which the application store (i.e. the Adito
     * server) is running.
     *
     * @return application store host
     */
    public String getApplicationStoreHost() {
        return applicationStoreHost;
    }

    /**
     * Get the port on which the application store (i.e. the Adito
     * server) is running.
     *
     * @return application store port
     */
    public int getApplicationStorePort() {
        return applicationStorePort;
    }

    /**
     * Get the protocol of where the application store (i.e. the Adito
     * server) is locate. This will be either <i>http</i> or <i>https</i>.
     *
     * @return application store protocol
     */
    public String getApplicationStoreProtocol() {
        return applicationStoreProtocol;
    }

    // Utility methods

    /**
     * Replace the standard tokens in the source string with the value know by
     * this VPN client.
     * <p>
     * Supports values include :- <code>${client:installDir}</code> - Client
     * installation directory<br/> <code>${adito:user}</code> -
     * Aditouser<br/> <code>${adito:host}</code> - Adito
     * host<br/> <code>${adito:port}</code> - Adito port<br/>
     * <code>${adito:protocol}</code> - Protocol (http / https)<br/>
     * <code>${adito:localProxyURL}</code> - Local proxy server URL<br/>
     * <code>${tunnel:XXXXX.hostname}</code> - Named tunnel hostname<br/>
     * <code>${tunnel:XXXXX.port}</code> - Named tunnel port<br/>
     *
     * @param str source string
     * @return processed string
     */
    public String replaceTokens(String str) {
        str = replaceAllTokens(str, "${client:installDir}", installDir.getAbsolutePath()); //$NON-NLS-1$
        str = replaceAllTokens(str, "${adito:user}", applicationStoreUser == null ? "" : applicationStoreUser); //$NON-NLS-1$ //$NON-NLS-2$
        str = replaceAllTokens(str, "${adito:host}", applicationStoreHost == null ? "" : applicationStoreHost); //$NON-NLS-1$ //$NON-NLS-2$
        str = replaceAllTokens(str, "${adito:port}", applicationStorePort == -1 ? "" : String.valueOf(applicationStorePort)); //$NON-NLS-1$ //$NON-NLS-2$
        str = replaceAllTokens(str, "${adito:protocol}", applicationStoreProtocol == null ? "" : applicationStoreProtocol); //$NON-NLS-1$ //$NON-NLS-2$
        str = replaceAllTokens(str, "${client:localProxyURL}", localProxyURL == null ? "" : localProxyURL); //$NON-NLS-1$ //$NON-NLS-2$
        for (Enumeration e = descriptorParams.keys(); e.hasMoreElements();) {
            String key = (String) e.nextElement();
            String val = (String) descriptorParams.get(key);
            str = replaceAllTokens(str, "${param:" + key + "}", val); //$NON-NLS-1$ //$NON-NLS-2$
        }
        return str;
    }

    public InputStream getDownloadFile(String name, String ticket, String filename) throws IOException {
        URL file = new URL(applicationStoreProtocol, applicationStoreHost, applicationStorePort, "/getApplicationFile.do" //$NON-NLS-1$
            + "?name=" + name + "&ticket=" + ticket + "&file=" + filename); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        if (events != null)
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.requestApplicationUsing"), new Object[] { file.toExternalForm() })); //$NON-NLS-1$

        URLConnection con = file.openConnection();
        con.setUseCaches(false);

        try {
            Method m = con.getClass().getMethod("setConnectTimeout", new Class[] { int.class }); //$NON-NLS-1$
            if (events != null) {
                events.debug(Messages.getString("ApplicationLauncher.runtime5")); //$NON-NLS-1$
            }
            m.invoke(con, new Object[] { new Integer(20000) });
            m = con.getClass().getMethod("setReadTimeout", new Class[] { int.class }); //$NON-NLS-1$
            m.invoke(con, new Object[] { new Integer(20000) });
        } catch (Throwable t) {
        }

        return con.getInputStream();
    }

    /**
     * Replace all occures of a token in a source string with another value
     *
     * @param source source string
     * @param token token to replace
     * @param value value to replace with
     * @return result
     */
    public static String replaceAllTokens(String source, String token, String value) {
      // Prevent infinite loop
      if(token.equals(value)) {
        return source;
      }
     
        int idx;

        do {
            idx = source.indexOf(token);

            if (idx > -1) {
                source = source.substring(0, idx) + value
                    + ((source.length() - idx <= token.length()) ? "" : source.substring(idx + token.length())); //$NON-NLS-1$
            }

        } while (idx > -1);

        return source;
    }


  private void addParameter(XMLElement e) throws IOException {
        String parameter = (String) e.getAttribute("name"); //$NON-NLS-1$
        String value = (String) e.getAttribute("value"); //$NON-NLS-1$
        if (events != null) {
            events.debug(MessageFormat.format(Messages.getString("ApplicationLauncher.addingParameter"), new Object[] { parameter, value }));//$NON-NLS-1$
        }

        descriptorParams.put(parameter, value);
    }

    protected void createTunnel(XMLElement e) throws IOException {
         throw new IOException(Messages.getString("ApplicationLauncher.tunnelRequiredButNoEventHandler")); //$NON-NLS-1$
    }

    private long generateChecksum(File f) throws IOException {

        Adler32 alder = new Adler32();
        CheckedInputStream in = new CheckedInputStream(new FileInputStream(f), alder);
        try {
            byte[] buf = new byte[4096];
            int read = 0;
            while ((read = in.read(buf)) > -1)
                ;

            alder = (Adler32) in.getChecksum();

            return alder.getValue();
        } finally {
            in.close();
        }
    }

    private void downloadFiles() throws IOException {

        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.downloadingFiles")); //$NON-NLS-1$

        if (events != null)
            events.startDownload(totalBytesToDownload);

        long bytesSoFar = 0;

        DownloadableFile df;
        for (int i = 0; i < filesToDownload.size(); i++) {
            df = (DownloadableFile) filesToDownload.elementAt(i);
            bytesSoFar = downloadFile(installDir,
                (df.getApplicationName() == null ? name : df.getApplicationName()),
                df.getName(),
                df.getTarget(),
                bytesSoFar,
                df.isExecutable(),
                df.isReadOnly(),
                df.getAliases(),
                df.getChecksum());
        }

        for (Enumeration e = sharedFilesToDowload.keys(); e.hasMoreElements();) {
            String name = (String) e.nextElement();
            df = (DownloadableFile) sharedFilesToDowload.get(name);
            bytesSoFar = downloadFile(sharedDir,
                (df.getApplicationName() == null ? name : df.getApplicationName()),
                df.getName(),
                df.getTarget(),
                bytesSoFar,
                df.isExecutable(),
                df.isReadOnly(),
                df.getAliases(),
                df.getChecksum());
        }

        if (events != null)
            events.completedDownload();

        if (events != null)
            events.debug(Messages.getString("ApplicationLauncher.completedDownloadingFiles")); //$NON-NLS-1$
    }

  public Vector getTunnels() {
    return EMPTY_VECTOR;
  }
   
  public void processErrorMessage(String text) {
      events.error(text);
    }
}
TOP

Related Classes of com.adito.agent.client.util.AbstractApplicationLauncher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.