resourcearchive.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 464 行

JAVA
464
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source 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. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the *   Free SoftwareFoundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.jca;import com.caucho.config.Config;import com.caucho.config.ConfigException;import com.caucho.jca.cfg.AdminObjectConfig;import com.caucho.jca.cfg.ConnectionDefinition;import com.caucho.jca.cfg.ConnectorConfig;import com.caucho.jca.cfg.MessageListenerConfig;import com.caucho.jca.cfg.ResourceAdapterConfig;import com.caucho.loader.DynamicClassLoader;import com.caucho.loader.EnvironmentBean;import com.caucho.log.Log;import com.caucho.util.L10N;import com.caucho.vfs.Jar;import com.caucho.vfs.Path;import com.caucho.vfs.ReadStream;import com.caucho.vfs.WriteStream;import javax.annotation.PostConstruct;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.logging.Level;import java.util.logging.Logger;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;/** * A resource archive (rar) */public class ResourceArchive implements EnvironmentBean{  static final L10N L = new L10N(ResourceArchive.class);  static final Logger log = Logger.getLogger(ResourceArchive.class.getName());  private ClassLoader _loader;    private Path _rootDir;  private Path _rarPath;  private ConnectorConfig _config;  /**   * Creates the application.   */  ResourceArchive()  {    _loader = Thread.currentThread().getContextClassLoader();  }  /**   * Sets the root directory.   */  public void setRootDirectory(Path rootDir)  {    _rootDir = rootDir;  }  /**   * Sets the root directory.   */  public Path getRootDirectory()  {    return _rootDir;  }  /**   * Returns the class loader.   */  public ClassLoader getClassLoader()  {    return _loader;  }  /**   * Sets the path to the .ear file   */  public void setRarPath(Path rarPath)  {    _rarPath = rarPath;  }  /**   * Returns the name.   */  public String getDisplayName()  {    return _config.getDisplayName();  }  /**   * Returns the resource adapter class.   */  public ResourceAdapterConfig getResourceAdapter()  {    return _config.getResourceAdapter();  }  /**   * Returns the resource adapter class.   */  public Class getResourceAdapterClass()  {    return _config.getResourceAdapter().getResourceadapterClass();  }  /**   * Returns the transaction support.   */  public String getTransactionSupport()  {    if (getResourceAdapter() != null)      return getResourceAdapter().getTransactionSupport();    else      return null;  }  /**   * Returns the matching connection factory class.   */  public ConnectionDefinition getConnectionDefinition(String type)  {    ResourceAdapterConfig raConfig = _config.getResourceAdapter();    if (raConfig != null)      return raConfig.getConnectionDefinition(type);    else      return null;  }  /**   * Returns the activation spec.   */  public MessageListenerConfig getMessageListener(String type)  {    ResourceAdapterConfig raConfig = _config.getResourceAdapter();    if (raConfig != null)      return raConfig.getMessageListener(type);    else      return null;  }  /**   * Returns the managed object definition.   */  public AdminObjectConfig getAdminObject(String type)  {    ResourceAdapterConfig raConfig = _config.getResourceAdapter();    if (raConfig != null)      return raConfig.getAdminObject(type);    else      return null;  }  /**   * Configures the resource.   */  @PostConstruct  public void init()    throws ConfigException  {    try {      expandRar();            ClassLoader loader = Thread.currentThread().getContextClassLoader();      for (; loader != null; loader = loader.getParent()) {	if (loader instanceof DynamicClassLoader)	  break;      }      if (loader == null)	throw new ConfigException(L.l("loader issues with resource adapter"));      addJars((DynamicClassLoader) loader, _rootDir);      addNative((DynamicClassLoader) loader, _rootDir);            Path raXml = _rootDir.lookup("META-INF/ra.xml");      if (! raXml.canRead())	throw new ConfigException(L.l("missing ra.xml for rar {0}.  .rar files require a META-INF/ra.xml file.",				      _rarPath));      _config = new ConnectorConfig();      new Config().configure(_config, raXml, "com/caucho/jca/jca.rnc");    } catch (ConfigException e) {      throw e;    } catch (Exception e) {      throw ConfigException.create(e);    }    log.info("ResourceArchive[" + _config.getDisplayName() + "] loaded");  }  void destroy()  {  }  /**   * Adds the jars from the rar file to the class loader.   */  private void addJars(DynamicClassLoader loader, Path path)    throws IOException  {    if (path.getPath().endsWith(".jar")) {      loader.addJar(path);    }    else if (path.isDirectory()) {      String []list = path.list();      for (int i = 0; i < list.length; i++)	addJars(loader, path.lookup(list[i]));    }  }  /**   * Adds the native paths from the rar file to the class loader.   */  private void addNative(DynamicClassLoader loader, Path path)    throws IOException  {    String fileName = path.getPath();    if (fileName.endsWith(".so")	|| fileName.endsWith(".dll")	|| fileName.endsWith(".jnilib")) {      loader.addNative(path);    }        else if (path.isDirectory()) {      String []list = path.list();      for (int i = 0; i < list.length; i++)	addNative(loader, path.lookup(list[i]));    }  }  /**   * Expand an rar file.  The _rarExpandLock must be obtained before the   * expansion.   *   * @param rar the rar file   * @param expandDir the directory which will contain the rar contents   */  private void expandRar()    throws IOException  {    Path rar = _rarPath;        if (! rar.canRead())      return;    try {      _rootDir.mkdirs();    } catch (Throwable e) {    }    Path expandDir = _rootDir;    Path tempDir = _rootDir.getParent().lookup(".temp");    Path dependPath = _rootDir.lookup("META-INF/resin-rar.timestamp");      // XXX: change to a hash    if (dependPath.canRead()) {      ReadStream is = null;      ObjectInputStream ois = null;      try {        is = dependPath.openRead();        ois = new ObjectInputStream(is);        long lastModified = ois.readLong();        long length = ois.readLong();        if (lastModified == rar.getLastModified() &&            length == rar.getLength())          return;      } catch (IOException e) {      } finally {        try {          if (ois != null)            ois.close();        } catch (IOException e) {        }	if (is != null)	  is.close();      }    }    try {      if (log.isLoggable(Level.INFO))        log.info("expanding rar " + rar + " to " + tempDir);            if (! tempDir.equals(expandDir)) {        tempDir.removeAll();      }      tempDir.mkdirs();      ReadStream rs = rar.openRead();       ZipInputStream zis = new ZipInputStream(rs);      try {        ZipEntry entry;        byte []buffer = new byte[1024];              while ((entry = zis.getNextEntry()) != null) {          String name = entry.getName();          Path path = tempDir.lookup(name);          if (entry.isDirectory())            path.mkdirs();          else {            long length = entry.getSize();            long lastModified = entry.getTime();            path.getParent().mkdirs();            WriteStream os = path.openWrite();            try {              int len;              while ((len = zis.read(buffer, 0, buffer.length)) > 0)                os.write(buffer, 0, len);            } catch (IOException e) {              log.log(Level.FINE, e.toString(), e);            } finally {              os.close();            }            if (lastModified > 0)              path.setLastModified(lastModified);          }        }      } finally {        try {          zis.close();        } catch (IOException e) {        }	rs.close();      }      if (! tempDir.equals(expandDir)) {        if (log.isLoggable(Level.INFO))          log.info("moving rar " + rar + " to " + expandDir);        // Close the cached zip streams because on NT that can lock        // the filesystem.        try {          Jar.clearJarCache();          removeAll(expandDir);        } catch (Throwable e) {          Jar.clearJarCache();          removeAll(expandDir);        }        moveAll(tempDir, expandDir);        removeAll(tempDir);      }    } catch (IOException e) {      log.log(Level.WARNING, e.toString(), e);      // If the jar is incomplete, it should throw an exception here.      return;    }        try {      dependPath.getParent().mkdirs();      WriteStream os = dependPath.openWrite();      ObjectOutputStream oos = new ObjectOutputStream(os);      oos.writeLong(rar.getLastModified());      oos.writeLong(rar.getLength());      oos.close();      os.close();    } catch (Throwable e) {      log.log(Level.WARNING, e.toString(), e);    }  }  /**   * Recursively remove all files in a directory.  Used for wars when   * they change.   *   * @param dir root directory to start removal   */  private static void removeAll(Path path)  {    try {      if (path.isDirectory()) {        String []list = path.list();        for (int i = 0; list != null && i < list.length; i++) {          removeAll(path.lookup(list[i]));        }      }              path.remove();    } catch (Throwable e) {      log.log(Level.WARNING, e.toString(), e);    }  }  /**   * Move directory A to directory B.   *   * @param source source directory   * @param target target directory   */  private static void moveAll(Path source, Path target)  {    try {      if (source.isDirectory()) {        try {          target.mkdirs();        } catch (IOException e) {        }                String []list = source.list();        for (int i = 0; list != null && i < list.length; i++) {          moveAll(source.lookup(list[i]), target.lookup(list[i]));        }      }      else        source.renameTo(target);    } catch (IOException e) {      log.log(Level.WARNING, e.toString(), e);    }  }  public String toString()  {    return getClass().getSimpleName() + "[" + getResourceAdapterClass() + "]";  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?