/**
  * プラグイン情報をロードします。
  *
  * @param file プラグイン情報
  * @param context コンテキスト
  * @throws PluginServiceException プラグイン機能に起因する問題が発生した場合
  * @throws ConfigurationFormatException 設定ファイルに問題がある場合
  * @throws IOException 入出力操作に起因する問題が発生した場合
  */
 public static void load(final String file, final Context context)
     throws PluginServiceException, ConfigurationFormatException, IOException {
   INSTANCE.doLoad(context.getResourceAsStream(file), context);
 }
  /**
   * プラグイン情報をロードします。
   *
   * @param aStream プラグイン情報
   * @param aContext コンテキスト
   * @throws PluginServiceException プラグイン機能に起因する問題が発生した場合
   * @throws ConfigurationFormatException 設定ファイルに問題がある場合
   * @throws IOException 入出力操作に起因する問題が発生した場合
   */
  @SuppressWarnings("unchecked")
  private void doLoad(final InputStream aStream, final Context aContext)
      throws PluginServiceException, ConfigurationFormatException, IOException {
    synchronized (plugins) {
      // Load plugin xml file.
      List<PluginXmlEntity> pluginList;
      try {
        Digester digester = new Digester();
        digester.addObjectCreate("azuki/plugin-list", ArrayList.class);
        digester.addObjectCreate("azuki/plugin-list/plugin", PluginXmlEntity.class);
        digester.addSetProperties("azuki/plugin-list/plugin");
        digester.addSetNext("azuki/plugin-list/plugin", "add");
        pluginList = digester.parse(aStream);
      } catch (SAXException ex) {
        error(ex);
        throw new ConfigurationFormatException(ex);
      } catch (IOException ex) {
        error(ex);
        throw ex;
      }

      try {
        for (int i = 0; i < pluginList.size(); i++) {
          PluginXmlEntity p = pluginList.get(i);
          Class<Plugin> clazz = (Class<Plugin>) Class.forName(p.getPlugin());
          Plugin plugin = clazz.newInstance();

          PluginEntity pe = new PluginEntity();
          pe.name = p.getName();
          pe.config = p.getConfig();
          pe.plugin = plugin;
          plugins.add(pe);
        }
      } catch (ClassNotFoundException ex) {
        error(ex);
        throw new PluginServiceException(ex);
      } catch (IllegalAccessException ex) {
        error(ex);
        throw new PluginServiceException(ex);
      } catch (InstantiationException ex) {
        error(ex);
        throw new PluginServiceException(ex);
      }

      // Support
      for (int i = 0; i < plugins.size(); i++) {
        Plugin plugin = plugins.get(i).getPlugin();
        // Support context
        if (plugin instanceof ContextSupport) {
          ((ContextSupport) plugin).setContext(aContext);
        }
        // Support configuration
        if (plugin instanceof ConfigurationSupport) {
          String config = plugins.get(i).config;
          if (StringUtility.isNotEmpty(config)) {
            Configuration configuration =
                new InputStreamConfiguration(aContext.getResourceAsStream(config));
            ((ConfigurationSupport) plugin).setConfiguration(configuration);
          } else {
            warn("Not setting config file.[" + plugins.get(i).getName() + "]");
          }
        }
      }

      // initialize
      for (int i = 0; i < plugins.size(); i++) {
        Plugin plugin = plugins.get(i).getPlugin();
        plugin.initialize();
      }

      // load
      for (int i = 0; i < plugins.size(); i++) {
        Plugin plugin = plugins.get(i).getPlugin();
        plugin.load();
      }
    }
  }