Package railo.runtime.config

Source Code of railo.runtime.config.DeployHandler

package railo.runtime.config;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import railo.commons.io.IOUtil;
import railo.commons.io.SystemUtil;
import railo.commons.io.compress.ZipUtil;
import railo.commons.io.log.LogAndSource;
import railo.commons.io.res.Resource;
import railo.commons.io.res.filter.ExtensionResourceFilter;
import railo.commons.io.res.filter.ResourceFilter;
import railo.commons.io.res.util.FileWrapper;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.lang.ExceptionUtil;
import railo.commons.lang.StringUtil;
import railo.commons.lang.SystemOut;
import railo.runtime.Info;
import railo.runtime.extension.RHExtension;
import railo.runtime.op.Caster;
import railo.runtime.op.Decision;
import railo.runtime.type.util.ListUtil;

public class DeployHandler {
 
 

  private static final ResourceFilter ALL_EXT = new ExtensionResourceFilter(new String[]{".re",".ra",".ras"});
  //private static final ResourceFilter ARCHIVE_EXT = new ExtensionResourceFilter(new String[]{".ra",".ras"});


  public static void deploy(Config config){
    synchronized (config) {
      Resource dir = getDeployDirectory(config);
      int ma = Info.getMajorVersion();
      int mi = Info.getMinorVersion();
      if(!dir.exists()) {
        if(ma>4 || ma==4 && mi>1) {// FUTURE remove the if contition
          dir.mkdirs();
        }
        return;
      }
     
      Resource[] children = dir.listResources(ALL_EXT);
      Resource child;
      String ext;
      for(int i=0;i<children.length;i++){
        child=children[i];
        try {
        // Railo archives
        ext=ResourceUtil.getExtension(child, null);
        if("ra".equalsIgnoreCase(ext) || "ras".equalsIgnoreCase(ext)) {
          deployArchive(config,child);
        }
       
        // Railo Extensions
        else if("re".equalsIgnoreCase(ext))
          deployExtension(config, child);
        }
        catch (ZipException e) {
          SystemOut.printDate(config.getErrWriter(),ExceptionUtil.getStacktrace(e, true));
        }
        catch (IOException e) {
          SystemOut.printDate(config.getErrWriter(),ExceptionUtil.getStacktrace(e, true));
        }
      }
    }
  }

  public static Resource getDeployDirectory(Config config) {
    return config.getConfigDir().getRealResource("deploy");
  }

  private static void deployArchive(Config config,Resource archive) throws ZipException, IOException {
    LogAndSource log = ((ConfigImpl)config).getDeployLogger();
    String type=null,virtual=null,name=null;
    boolean readOnly,topLevel,hidden,physicalFirst;
    short inspect;
    InputStream is = null;
    ZipFile file=null;
    try {
    file=new ZipFile(FileWrapper.toFile(archive));
    ZipEntry entry = file.getEntry("META-INF/MANIFEST.MF");
   
    // no manifest
    if(entry==null) {
      log.error("archive","cannot deploy Railo Archive ["+archive+"], file is to old, the file does not have a MANIFEST.");
      moveToFailedFolder(archive);
      return;
    }
   
      is = file.getInputStream(entry);
      Manifest manifest = new Manifest(is);
        Attributes attr = manifest.getMainAttributes();
       
        //id = unwrap(attr.getValue("mapping-id"));
        type = unwrap(attr.getValue("mapping-type"));
        virtual = unwrap(attr.getValue("mapping-virtual-path"));
        name = ListUtil.trim(virtual, "/");
        readOnly = Caster.toBooleanValue(unwrap(attr.getValue("mapping-readonly")),false);
        topLevel = Caster.toBooleanValue(unwrap(attr.getValue("mapping-top-level")),false);
        inspect = ConfigWebUtil.inspectTemplate(unwrap(attr.getValue("mapping-inspect")), ConfigImpl.INSPECT_UNDEFINED);
        if(inspect==ConfigImpl.INSPECT_UNDEFINED) {
          Boolean trusted = Caster.toBoolean(unwrap(attr.getValue("mapping-trusted")),null);
          if(trusted!=null) {
            if(trusted.booleanValue()) inspect=ConfigImpl.INSPECT_NEVER;
            else inspect=ConfigImpl.INSPECT_ALWAYS;
         
        }
        hidden = Caster.toBooleanValue(unwrap(attr.getValue("mapping-hidden")),false);
        physicalFirst = Caster.toBooleanValue(unwrap(attr.getValue("mapping-physical-first")),false);
    }
    finally{
      IOUtil.closeEL(is);
      ZipUtil.close(file);
    }
    Resource trgDir = config.getConfigDir().getRealResource("archives").getRealResource(type).getRealResource(name);
    Resource trgFile = trgDir.getRealResource(archive.getName());
    trgDir.mkdirs();
   
    // delete existing files
   
    try {
      ResourceUtil.deleteContent(trgDir, null);
      ResourceUtil.moveTo(archive, trgFile,true);
     
      log.info("archive","add "+type+" mapping ["+virtual+"] with archive ["+trgFile.getAbsolutePath()+"]");
      if("regular".equalsIgnoreCase(type))
        ConfigWebAdmin.updateMapping((ConfigImpl)config,virtual, null, trgFile.getAbsolutePath(), "archive", inspect, topLevel);
      else if("cfc".equalsIgnoreCase(type))
        ConfigWebAdmin.updateComponentMapping((ConfigImpl)config,virtual, null, trgFile.getAbsolutePath(), "archive", inspect);
      else if("ct".equalsIgnoreCase(type))
        ConfigWebAdmin.updateCustomTagMapping((ConfigImpl)config,virtual, null, trgFile.getAbsolutePath(), "archive", inspect);
     
       
    }
    catch (Throwable t) {
      moveToFailedFolder(archive);
      log.error("archive",ExceptionUtil.getStacktrace(t, true));
    }
  }
 

  private static void deployExtension(Config config, Resource ext) {
    ConfigImpl ci = (ConfigImpl)config;
    boolean isWeb=config instanceof ConfigWeb;
    String type=isWeb?"web":"server";
    LogAndSource log = ((ConfigImpl)config).getDeployLogger();
   
    // Manifest
    Manifest manifest = null;
    ZipInputStream zis=null;
        try {
          zis = new ZipInputStream( IOUtil.toBufferedInputStream(ext.getInputStream()) ) ;    
          ZipEntry entry;
          String name;
          while ( ( entry = zis.getNextEntry()) != null ) {
            name=entry.getName();
            if(!entry.isDirectory() && name.equalsIgnoreCase("META-INF/MANIFEST.MF")) {
              manifest = toManifest(config,zis,null);
            }
              zis.closeEntry() ;
          }
        }
        catch(Throwable t){
          log.error("extension", ExceptionUtil.getStacktrace(t, true));
      moveToFailedFolder(ext);
      return;
        }
        finally {
          IOUtil.closeEL(zis);
        }
       
        int minCoreVersion=0;
        double minLoaderVersion=0;
        String strMinCoreVersion="",strMinLoaderVersion="",version=null,name=null,id=null;
       
        if(manifest!=null) {
          Attributes attr = manifest.getMainAttributes();
          // version
          version=unwrap(attr.getValue("version"));


          // id
          id=unwrap(attr.getValue("id"));
         
          // name
          name=unwrap(attr.getValue("name"));

          // core version
          strMinCoreVersion=unwrap(attr.getValue("railo-core-version"));
          minCoreVersion=Info.toIntVersion(strMinCoreVersion,minCoreVersion);
         
          // loader version
          strMinLoaderVersion=unwrap(attr.getValue("railo-loader-version"));
          minLoaderVersion=Caster.toDoubleValue(strMinLoaderVersion,minLoaderVersion);
         
        }
        if(StringUtil.isEmpty(name,true)) {
          name=ext.getName();
          int index=name.lastIndexOf('.');
          name=name.substring(0,index-1);
        }
        name=name.trim();
       
       
        // check core version
    if(minCoreVersion>Info.getVersionAsInt()) {
      log.error("extension", "cannot deploy Railo Extension ["+ext+"], Railo Version must be at least ["+strMinCoreVersion+"].");
      moveToFailedFolder(ext);
      return;
    }

    // check loader version
    if(minLoaderVersion>SystemUtil.getLoaderVersion()) {
      log.error("extension", "cannot deploy Railo Extension ["+ext+"], Railo Loader Version must be at least ["+strMinLoaderVersion+"], update the railo.jar first.");
      moveToFailedFolder(ext);
      return;
    }
    // check id
    if(!Decision.isUUId(id)) {
      log.error("extension", "cannot deploy Railo Extension ["+ext+"], this Extension has no valid id ["+id+"],id must be a valid UUID.");
      moveToFailedFolder(ext);
      return;
    }
   
   
   
   
    Resource trgFile=null;
    try{
      ConfigWebAdmin.removeRHExtension(ci,id);
     
      Resource trgDir = config.getConfigDir().getRealResource("extensions").getRealResource(type).getRealResource(name);
      trgFile = trgDir.getRealResource(ext.getName());
      trgDir.mkdirs();
      ResourceUtil.moveTo(ext, trgFile,true);
    }
      catch(Throwable t){
        log.error("extension", ExceptionUtil.getStacktrace(t, true));
      moveToFailedFolder(ext);
      return;
      }
     
    try {
          zis = new ZipInputStream( IOUtil.toBufferedInputStream(trgFile.getInputStream()) ) ;    
          ZipEntry entry;
          String path;
          String fileName;
          List<String> jars=new ArrayList<String>(), flds=new ArrayList<String>(), tlds=new ArrayList<String>(), contexts=new ArrayList<String>(), applications=new ArrayList<String>();
          while ( ( entry = zis.getNextEntry()) != null ) {
            path=entry.getName();
            fileName=fileName(entry);
            // jars
            if(!entry.isDirectory() && (startsWith(path,type,"jars") || startsWith(path,type,"jar") || startsWith(path,type,"lib") || startsWith(path,type,"libs")) && StringUtil.endsWithIgnoreCase(path, ".jar")) {
              log.info("extension","deploy jar "+fileName);
              ConfigWebAdmin.updateJar(config,zis,fileName,false);
              jars.add(fileName);
            }
           
            // flds
            if(!entry.isDirectory() && startsWith(path,type,"flds") && StringUtil.endsWithIgnoreCase(path, ".fld")) {
              log.info("extension","deploy fld "+fileName);
              ConfigWebAdmin.updateFLD(config, zis, fileName,false);
              flds.add(fileName);
            }
           
            // tlds
            if(!entry.isDirectory() && startsWith(path,type,"tlds") && StringUtil.endsWithIgnoreCase(path, ".tld")) {
              log.info("extension","deploy tld "+fileName);
              ConfigWebAdmin.updateTLD(config, zis, fileName,false);
              tlds.add(fileName);
            }
           
            // context
            String realpath;
            if(!entry.isDirectory() && startsWith(path,type,"context") && !StringUtil.startsWith(fileName(entry), '.')) {
              realpath=path.substring(8);
              //log.info("extension","deploy context "+realpath);
              log.info("extension","deploy context "+realpath);
              ConfigWebAdmin.updateContext(ci, zis, realpath,false);
              contexts.add(realpath);
            }
           
            // applications
            if(!entry.isDirectory() && startsWith(path,type,"applications") && !StringUtil.startsWith(fileName(entry), '.')) {
              realpath=path.substring(13);
              //log.info("extension","deploy context "+realpath);
              log.info("extension","deploy application "+realpath);
              ConfigWebAdmin.updateApplication(ci, zis, realpath,false);
              applications.add(realpath);
            }
           
           
              zis.closeEntry() ;
          }
         
          //installation successfull
         
          ConfigWebAdmin.updateRHExtension(ci,
              new RHExtension(id,name,version,
              jars.toArray(new String[jars.size()]),
              flds.toArray(new String[flds.size()]),
              tlds.toArray(new String[tlds.size()]),
              contexts.toArray(new String[contexts.size()]),
              applications.toArray(new String[applications.size()])));
         
        }
      catch(Throwable t){
        // installation failed
       
        log.error("extension",ExceptionUtil.getStacktrace(t, true));
      moveToFailedFolder(trgFile);
      return;
      }
        finally {
          IOUtil.closeEL(zis);
        }
  }

  private static Manifest toManifest(Config config,InputStream is, Manifest defaultValue) {
    try {
      String cs = config.getResourceCharset();
      String str = IOUtil.toString(is,cs);
      if(StringUtil.isEmpty(str,true)) return defaultValue;
      str=str.trim()+"\n";
      return new Manifest(new ByteArrayInputStream(str.getBytes(cs)));
    }
    catch (Throwable t) {
      return defaultValue;
    }
  }

  private static boolean startsWith(String path,String type, String name) {
    return StringUtil.startsWithIgnoreCase(path, name+"/") || StringUtil.startsWithIgnoreCase(path, type+"/"+name+"/");
  }

  private static String fileName(ZipEntry entry) {
    String name = entry.getName();
    int index=name.lastIndexOf('/');
    if(index==-1) return name;
    return name.substring(index+1);
  }

  private static void moveToFailedFolder(Resource archive) {
    Resource dir = archive.getParentResource().getRealResource("failed-to-deploy");
    Resource dst = dir.getRealResource(archive.getName());
    dir.mkdirs();
   
    try {
      if(dst.exists()) dst.remove(true);
      ResourceUtil.moveTo(archive, dst,true);
    }
    catch (Throwable t) {}
   
    // TODO Auto-generated method stub
   
  }

  private static String unwrap(String value) {
    if(value==null) return "";
    String res = unwrap(value,'"');
    if(res!=null) return res; // was double quote
   
    return unwrap(value,'\''); // try single quote unwrap, when there is no double quote.
  }
 
  private static String unwrap(String value, char del) {
    value=value.trim();
    if(StringUtil.startsWith(value, del) && StringUtil.endsWith(value, del)) {
      return value.substring(1, value.length()-1);
    }
    return value;
  }
 
}
TOP

Related Classes of railo.runtime.config.DeployHandler

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.