Package org.infoglue.cms.controllers.kernel.impl.simple

Source Code of org.infoglue.cms.controllers.kernel.impl.simple.AntRun

/* ===============================================================================
*
* Part of the InfoGlue Content Management Platform (www.infoglue.org)
*
* ===============================================================================
*
*  Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2, as published by the
* Free Software Foundation. See the file LICENSE.html for more information.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, including 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. / 59 Temple
* Place, Suite 330 / Boston, MA 02111-1307 / USA.
*
* ===============================================================================
*/

/*
* Created on 2003-apr-04
*
* ERROR IN REMOVEPACKAGE, FIX IT!
*
* */
package org.infoglue.cms.controllers.kernel.impl.simple;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.Iterator;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Ant;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.ValidationException;
import org.infoglue.cms.entities.kernel.BaseEntityVO;
import org.infoglue.cms.entities.up2date.UpdateCollection;
import org.infoglue.cms.entities.up2date.UpdatePackage;
import org.xml.sax.InputSource;


/**
*
* Core infoglue up2date functionallity is provided through
* this controller.
*
* The constructor takes two arguments
* 1: url to the updateservers xml-file of available packages
*    This delegates the problem of mirror handling and finding
*    a working updateserver to the calling class.  
*
* 2: path to up2date directory residing directly below the toplevel
*    codebase directory. Ant operates with this directory as the basedirectory
*    so the ant-files delivered by the updateserver should operate on ".." to
*    get access to the base directory.
*
* The update process briefly:
*
* Overview:
* Available updates are served by a InfoGlue CMS repository
* where developers easily can publish update packages and
* deployment logic for installing those packages.
*
* The list of available updates, are served in xml-format from
* the InfoGlue Update Server. When requesting this document, a list
* of allready installed packages is passed to the server along with
* the query.
* The returned document looks something like this:
*
*   <update-collection>
*    <update-package>
*      <package-id>pid</package-id>
*      <title>Title</title>
*      <description>breif description</description>
*      <url>http://url_to_ant_install_script</url>
*      <details-url>http://url_to_html-info_page_describing_the_package</details-url>
*    </update-package>
*    <update-package>
*      ...
*    <update-package>
</update-collection>
*
* This document is retrieved by this controller on the client system
* and is unmarshaled to objects and placed in a list of available packages.
*
* The list is presented to the user (administrator of the client system)
* in the management tool. Where he may chose to access the detail page on
* the server, or install the package.
*
* Package Installation:
* When the user has decided that the has come to install an update. This class
* retrieves the ant-script (actually using ants get task) that shall be used
* for the installation. The url to the script is found in packagedefinition.
*
* The file is stored locally on the client system in CMS_BASEDIR/up2date/PID.xml
* Another ant session is started, using this file, and running target "runUpdate"
* Typically this target gets a zip-file from the server and unpacks it over the
* current codebase. But first a backup is made. But all this is up to
* the Update Server. A target "unInstall" should also exist in this file.
* Current setup at www.infoglue.org updateserver also executes two additional targets
* beforeUpdate and afterUpdate which can be edited by the packageauthor for each package
*
* After the update is made, the package object are added to the list of installed
* packages, and later marshalled to CMS_BASEDIR/up2date/installed.xml
*
*
*
* @author Stefan Sik
*
*
*
*/
public class UpdateController extends BaseController
{
  private final static Logger logger = Logger.getLogger(UpdateController.class.getName());

  /**
   *
   */
 
  // Initial handling of compatibility in the server response.
  // Make this better later
  private String protocolVersion = "20";
  // Protocol version 12 adds title to the package description
  
  private String path = "";
  private String url = "";
  Mapping mapping;
 
  public UpdateController(String url, String path) throws FileNotFoundException, IOException, MappingException
  {
    // set variables
    // Create and load the castor xml mapping
    this.path = path;
    this.url = url;
    mapping = new Mapping();
    mapping.loadMapping(new InputSource(new FileReader(path + "mapping.xml")));
  }

  public void refreshAvailableUpdates()
  {
    // Expire the cached availableUpdates list
    UpdateListHandler.setAvailableUpdates(null);
  }
 
  public Date getLatestRefresh()
  {
    return UpdateListHandler.getLatestRefresh();
  }
 
  public Vector getAvailableUpdates()
  {
    logger.info("Get Available updates");

    if (UpdateListHandler.getAvailableUpdates() == null)
    {
      logger.info("Getting from updateserver");
      Vector ret = new Vector();   
 
       try
       {
        Unmarshaller unmar = new Unmarshaller(mapping);
        unmar.setWhitespacePreserve(true);
        unmar.setValidation(false);
        // Fix url to updateserver, so that it filters
        // packages allready installed locally
        // also submit updatesystemversion
                if(url.indexOf("?") == -1)
                    url += "?v=" + protocolVersion;
                else
                    url += "&v=" + protocolVersion;
       
        Vector installed = getInstalledUpdates();
        Iterator iterator = installed.iterator();
       
        while (iterator.hasNext()) {
            UpdatePackage u = (UpdatePackage) iterator.next();
            url += "&p=" + u.getPackageId();
        }
       
        URL u = new URL(url);
        URLConnection urlConn = u.openConnection();
        urlConn.setAllowUserInteraction(false);
        urlConn.setUseCaches (false);
       
        UpdateCollection coll = (UpdateCollection) unmar.unmarshal( new InputStreamReader(urlConn.getInputStream()));
        ret = coll.getUpdatePackageList();
      }
      catch (ValidationException e2)
      {
        e2.printStackTrace();
      } catch (MalformedURLException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      } catch (MappingException e) {
        e.printStackTrace();
      } catch (MarshalException e) {
        e.printStackTrace();
      }
 
      UpdateListHandler.setAvailableUpdates(ret);
    }
    return UpdateListHandler.getAvailableUpdates();
  }
 
  public Vector getInstalledUpdates()
  {
    logger.info("GetInstalled Updates");

    Unmarshaller unmar = null;
    UpdateCollection coll = new UpdateCollection();
    try
    {
      unmar = new Unmarshaller(mapping);
      unmar.setWhitespacePreserve(true);
      unmar.setValidation(false);
      coll = (UpdateCollection) unmar.unmarshal(new InputSource(new FileReader(path + "installed.xml")));
    }
    catch (MarshalException e2)
    {
      logger.info("Marshal exception");
    }
    catch (ValidationException e2)
    {
      e2.printStackTrace();
    }
    catch (FileNotFoundException e2)
    {
      logger.info("No packages found");
    }
    catch (MappingException e1)
    {
      e1.printStackTrace();
    }

    logger.info("Leaving GetInstalled Updates");
    return coll.getUpdatePackageList();
  }

  private void addInstalledUpdate(UpdatePackage upd)
  {
      Unmarshaller unmar = null;
      try {
        unmar = new Unmarshaller(mapping);
        unmar.setWhitespacePreserve(true);
        unmar.setValidation(false);
      } catch (MappingException e1) {
        e1.printStackTrace();
      }
      UpdateCollection coll = new UpdateCollection();
      try {
        coll =
          (UpdateCollection) unmar.unmarshal(
            new InputSource(
              new FileReader(path + "installed.xml")));
      } catch (MarshalException e2) {
        e2.printStackTrace();
      } catch (ValidationException e2) {
        e2.printStackTrace();
      } catch (FileNotFoundException e2) {
        logger.info("No previous installations");
      }
      coll.getUpdatePackageList().add(upd);
     
      Marshaller marshaller = null;
      try {
        marshaller =
          new Marshaller(
            new FileWriter(new File(path + "installed.xml")));
      } catch (IOException e3) {
        e3.printStackTrace();
      }
      try {
        marshaller.setMapping(mapping);
      } catch (MappingException e4) {
        e4.printStackTrace();
      }
      try {
        marshaller.marshal(coll);
      } catch (MarshalException e5) {
        e5.printStackTrace();
      } catch (ValidationException e5) {
        e5.printStackTrace();
      }
  }

  private void removeInstalledUpdate(UpdatePackage upd)
  {

    Unmarshaller unmar = null;
    try {
      unmar = new Unmarshaller(mapping);
      unmar.setWhitespacePreserve(true);
      unmar.setValidation(false);
    } catch (MappingException e1) {
      e1.printStackTrace();
    }
    UpdateCollection coll = new UpdateCollection();
    try {
      coll =
        (UpdateCollection) unmar.unmarshal(
          new InputSource(
            new FileReader(path + "installed.xml")));
    } catch (MarshalException e2) {
      e2.printStackTrace();
    } catch (ValidationException e2) {
      e2.printStackTrace();
    } catch (FileNotFoundException e2) {
      logger.info("No previous installations");
    }

      // Find the update with id updatePackageId
      Iterator iterator = coll.getUpdatePackageList().iterator();
      while (iterator.hasNext()) {
          UpdatePackage u = (UpdatePackage) iterator.next();
          if(upd.getPackageId().compareTo(u.getPackageId())==0)
          {
          coll.getUpdatePackageList().remove(u);
          iterator = coll.getUpdatePackageList().iterator();
          }
      }


     
      Marshaller marshaller = null;
      try {
        marshaller =
          new Marshaller(
            new FileWriter(new File(path + "installed.xml")));
      } catch (IOException e3) {
        e3.printStackTrace();
      }
      try {
        marshaller.setMapping(mapping);
      } catch (MappingException e4) {
        e4.printStackTrace();
      }
      try {
        marshaller.marshal(coll);
      } catch (MarshalException e5) {
        e5.printStackTrace();
      } catch (ValidationException e5) {
        e5.printStackTrace();
      }
  }
 
  public void runUpdatePackage(String updatePackageId, OutputStreamWriter writer) throws IOException
  {
    // Find the update with id updatePackageId
    Vector updates = getAvailableUpdates();
    Iterator iterator = updates.iterator();
    while (iterator.hasNext()) {
        UpdatePackage u = (UpdatePackage) iterator.next();
        if(updatePackageId.compareTo(u.getPackageId())==0)
        {
          logger.info("Found package to install: " + u.getPackageId());
          runUpdatePackage(u, writer);
          break;
        }
    }
   
  }

  public void unInstallPackage(String updatePackageId, PrintWriter out) throws MalformedURLException
  {
    // Find the update with id updatePackageId
    Vector updates = getInstalledUpdates();
    Iterator iterator = updates.iterator();
    while (iterator.hasNext()) {
        UpdatePackage u = (UpdatePackage) iterator.next();
        if(updatePackageId.compareTo(u.getPackageId())==0)
        {
          logger.info("Found package to uninstall: " + u.getPackageId());
        unInstallPackage(u, out);
        break;
        }
    }
   
  }

  public void runUpdatePackage(UpdatePackage upd, final OutputStreamWriter out) throws IOException
  {
   
    /* TODO:
     * Capture output from ant session and return it, s� that we can produce
     * a summary of the installation to the user.
     */
      try {
     
      // Get the zip-file!
      String url = upd.getDecodedBinaryUrl();
      out.write("Downloading the package");
      out.flush();
      String zipFile = path + "autoUpdate/" + upd.getPackageId() + ".zip";
      getFile(url, zipFile, upd.getBinarySize().intValue(), out);
     
      // Get the ant-file and run it!
      String antFile = path + upd.getPackageId() + ".xml";
      getFile(upd.getDecodedUrl(), antFile, -1, out);
      out.flush();
 
      // Run the ant file!
      final class AntRun extends Ant {
        public AntRun() {
          project = new Project();
          project.init();
       
      }
      AntRun a = new AntRun();
      a.setAntfile(antFile);
      a.setDir(new File(path));
      a.setTarget("runUpdate");
      out.write("Executing ant update script...<br>");
      out.flush();
      a.execute();
 
 
      // Add this update!
      out.write("Finalizing...<br>");
      out.flush();
      refreshAvailableUpdates();
      addInstalledUpdate(upd);
 
      // We are done
      out.write("DONE!<br>");
      out.flush();
      }
      catch(BuildException e)
      {
      out.write(e.getMessage());
      out.write("<br>");
         
      } catch (MalformedURLException e)
        {
      out.write(e.getMessage());
      out.write("<br>");
        }
  }
 
  public void unInstallPackage(UpdatePackage upd, final PrintWriter out) throws MalformedURLException
  {
   
    /* TODO:
     * Capture output from ant session and return it, s� that we can produce
     * a summary of the installation to the user.
     *
     * Should maybe use outputstream instead of printwriter
     */
    out.println("About to run uninstallation...<br>");

    final String antfile = upd.getPackageId();
    String destFile = path + antfile + ".xml";

    // Run the ant file!
    final class AntRun extends Ant {
      public AntRun() {
        project = new Project();
        project.init();
     
    }
    AntRun a = new AntRun();
    a.setAntfile(destFile);
    a.setDir(new File(path));
    a.setTarget("unInstall");
    out.println("Running Ant...<br>");
    a.execute();


    // Add this update!
    out.println("Finalizing...<br>");
    refreshAvailableUpdates();

    removeInstalledUpdate(upd);
   
    // We are done
    out.println("DONE!<br>");
  }
 
 
 
  private void getFile(String src, String dest, int size, OutputStreamWriter out) throws IOException
  {
    File destFile = new File(dest);
    destFile.getParentFile().mkdirs();
    URL u = new java.net.URL(src);
    URLConnection urlConn = u.openConnection();
    urlConn.setAllowUserInteraction(false);
    urlConn.setUseCaches (false);
    InputStream is = urlConn.getInputStream();
    String fileName = dest.substring(dest.lastIndexOf("/"));

    FileOutputStream fo = new FileOutputStream(new File(dest));

    int cnt = 0;
    int cntcheck = 0;
    int steps = 50;
    int interval = size / steps;
   
        out.write("<font color='blue'><pre>");
        for(int x = 0; x< steps;x++)
      out.write("_");
        out.write("<br>");
    out.flush();

   
    byte[] buffer = new byte[64];// Or any length you want
      BufferedInputStream br = new BufferedInputStream(urlConn.getInputStream());
      for (int lengthRead = 0; (lengthRead = br.read(buffer)) >= 0;)
      {
          cnt+=lengthRead;
          fo.write(buffer, 0, lengthRead);
         
          if(size > 0)
          {
        if(cnt % (size / steps) < cntcheck)
        {
          out.write("*");
          out.flush();
        }
            cntcheck = cnt % (size / steps);
          }
      }
        if(size <= 0)
        {
            for(int x = 0; x< steps;x++)
        out.write("*");
        }
    out.flush();

    out.write("</font><font color='green'> [OK] - " + fileName + "</font>");
    out.write("<br>");
        out.write("</pre>");
    out.flush();
    is.close();
    fo.close();
    out.flush();
  }

    public BaseEntityVO getNewVO()
    {
        // TODO Auto-generated method stub
        return null;
    }

}
TOP

Related Classes of org.infoglue.cms.controllers.kernel.impl.simple.AntRun

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.