Package com.quickwebframework.web.util

Source Code of com.quickwebframework.web.util.BundleInfo

package com.quickwebframework.web.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.osgi.framework.Version;

/**
* Bundle信息类(信息来源于META-INF/MANIFEST.MF文件)
*
* @author aaa
*
*/
public class BundleInfo {

  public final static String METAINF_FILE_PATH = "META-INF/MANIFEST.MF";
  public final static String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
  public final static String BUNDLE_VERSION = "Bundle-Version";
  public final static String BUNDLE_REQUIRE_BUNDLE = "Require-Bundle";
  public final static String BUNDLE_IMPORT_PACKAGE = "Import-Package";
  public final static String BUNDLE_EXPORT_PACKAGE = "Export-Package";

  // 插件内容字节数组
  private byte[] bundleContentBytes;
  private String bundleName;
  private Version bundleVersion;
  // 需要的Bundle名称列表
  private List<String> requireBundleNameList;
  // 导入的包列表
  private List<String> importPackageList;
  // 导出的包列表
  private List<String> exportPackageList;

  // 从清单文件中得到对应的Properties
  private Properties getBundleManifestProperties(
      InputStream manifestInputStream) {
    try {
      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      IOUtils.copy(manifestInputStream, outputStream);

      byte[] buffer = outputStream.toByteArray();
      String text = new String(buffer, "utf-8");
      text = text.replace("\r\n ", "").replace("\n ", "");

      StringReader reader = new StringReader(text);
      InputStream input = new ReaderInputStream(reader);

      // 加载清单文件
      Properties prop = new Properties();
      prop.load(input);
      return prop;
    } catch (Exception ex) {
      throw new RuntimeException(ex);
    }
  }

  /**
   * 从Properties对象中加载信息
   *
   * @param prop
   */
  public void loadProperties(Properties prop) {
    // 得到插件的名称和版本
    bundleName = prop.getProperty(BUNDLE_SYMBOLIC_NAME);
    bundleVersion = Version.parseVersion(prop.getProperty(BUNDLE_VERSION));

    // 需要的Bundle
    String requireBundleAllString = prop.getProperty(BUNDLE_REQUIRE_BUNDLE);
    if (requireBundleAllString != null) {
      String[] lineArray = requireBundleAllString.split(",");
      for (String line : lineArray) {
        line = line.trim();

        String tmpName = null;
        if (line.contains(";")) {
          tmpName = line.split(";")[0].trim();
        } else {
          tmpName = line;
        }
        requireBundleNameList.add(tmpName);
      }
    }

    // 导入的包
    String importPackageAllString = prop.getProperty(BUNDLE_IMPORT_PACKAGE);
    if (importPackageAllString != null) {
      String[] lineArray = importPackageAllString.split(",");
      for (String line : lineArray) {
        line = line.trim();

        String tmpName = null;
        if (line.contains(";")) {
          tmpName = line.split(";")[0].trim();
        } else {
          tmpName = line;
        }
        importPackageList.add(tmpName);
      }
    }
    // 导出的包
    String exportPackageAllString = prop.getProperty(BUNDLE_EXPORT_PACKAGE);
    if (exportPackageAllString != null) {
      String[] lineArray = exportPackageAllString.split(",");
      for (String line : lineArray) {
        line = line.trim();

        String tmpName = null;
        if (line.contains(";")) {
          tmpName = line.split(";")[0].trim();
        } else {
          tmpName = line;
        }
        exportPackageList.add(tmpName);
      }
    }
  }

  /**
   * 从清单文件中加载信息
   *
   * @param manifestInputStream
   */
  public void loadManifestResource(InputStream manifestInputStream) {
    // 从插件的清单文件中得到Properties对象
    Properties prop = getBundleManifestProperties(manifestInputStream);
    loadProperties(prop);
  }

  public BundleInfo() {
    init(null);
  }

  /**
   * 构造函数
   *
   * @param bundleInputStream
   *            插件的输入流,比如插件的文件流,网络流等
   */
  public BundleInfo(InputStream bundleInputStream) {
    init(bundleInputStream);
  }

  private void init(InputStream inputStream) {
    requireBundleNameList = new ArrayList<String>();
    importPackageList = new ArrayList<String>();
    exportPackageList = new ArrayList<String>();

    if (inputStream != null)
      setBundleInputStream(inputStream);
  }

  /**
   * 得到插件的输入流
   *
   * @return
   */
  public InputStream getBundleInputStream() {
    // 因为会被调用多次,所以每次初始化化一个ByteArrayInputStream
    return new ByteArrayInputStream(bundleContentBytes);
  }

  /**
   * 设置插件的输入流
   *
   * @param bundleInputStream
   */
  public void setBundleInputStream(InputStream bundleInputStream) {
    try {
      // 先将输入流读取到一个ByteArrayOutputStream中
      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      IOUtils.copy(bundleInputStream, outputStream);
      // 得到这个插件的字节数组
      bundleContentBytes = outputStream.toByteArray();
      if (bundleContentBytes.length < 2) {
        throw new RuntimeException("输入流中的字节数小于2,不是一个ZIP压缩流!");
      }
      if (bundleContentBytes[0] != 'P' || bundleContentBytes[1] != 'K') {
        throw new RuntimeException("输入流中的前两个字节不是'PK',不是一个合法的ZIP压缩流!");
      }
      InputStream inputStream = getBundleInputStream();
      // 从ZIP流中解压并读出META-INF/MANIFEST.MF文件的内容
      ZipInputStream zipInputStream = new ZipInputStream(inputStream);
      long manifestFileLength = -1;
      while (true) {
        ZipEntry zipEntry = zipInputStream.getNextEntry();
        if (zipEntry == null)
          break;
        if (zipEntry.getName().equals(METAINF_FILE_PATH)) {
          manifestFileLength = zipEntry.getSize();
          break;
        }
      }
      if (manifestFileLength <= 0) {
        throw new RuntimeException(
            "ZIP压缩流中未能找到META-INF/MANIFEST.MF清单文件!");
      }
      // 将manifest文件的内容从压缩流中解压出来
      outputStream = new ByteArrayOutputStream();
      IOUtils.copy(zipInputStream, outputStream);
      zipInputStream.close();

      // 加载清单文件
      loadManifestResource(new ByteArrayInputStream(
          outputStream.toByteArray()));
    } catch (Exception ex) {
      throw new RuntimeException(ex);
    }
  }

  public String getBundleName() {
    return bundleName;
  }

  public Version getBundleVersion() {
    return bundleVersion;
  }

  public List<String> getRequireBundleNameList() {
    return requireBundleNameList;
  }

  public List<String> getImportPackageList() {
    return importPackageList;
  }

  public List<String> getExportPackageList() {
    return exportPackageList;
  }
}
TOP

Related Classes of com.quickwebframework.web.util.BundleInfo

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.