content: /**
   * Copyright 2017 JessYan
   * <p>
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * <p>
   * http://www.apache.org/licenses/LICENSE-2.0
   * <p>
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package <%= appPackage %>.integration;
  
  import android.content.Context;
  import android.content.pm.ApplicationInfo;
  import android.content.pm.PackageManager;
  
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * ================================================
   * 用于解析 AndroidManifest 中的 Meta 属性
   * 配合 {@link ConfigModule} 使用
   * <p>
   * Created by JessYan on 12/04/2017 14:41
   * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
   * <a href="https://github.com/JessYanCoding">Follow me</a>
   * ================================================
   */
  public final class ManifestParser {
      private static final String MODULE_VALUE = "ConfigModule";
  
      private final Context context;
  
      public ManifestParser(Context context) {
          this.context = context;
      }
  
      public List<ConfigModule> parse() {
          List<ConfigModule> modules = new ArrayList<ConfigModule>();
          try {
              ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
                      context.getPackageName(), PackageManager.GET_META_DATA);
              if (appInfo.metaData != null) {
                  for (String key : appInfo.metaData.keySet()) {
                      if (MODULE_VALUE.equals(appInfo.metaData.get(key))) {
                          modules.add(parseModule(key));
                      }
                  }
              }
          } catch (PackageManager.NameNotFoundException e) {
              throw new RuntimeException("Unable to find metadata to parse ConfigModule", e);
          }
  
          return modules;
      }
  
      private static ConfigModule parseModule(String className) {
          Class<?> clazz;
          try {
              clazz = Class.forName(className);
          } catch (ClassNotFoundException e) {
              throw new IllegalArgumentException("Unable to find ConfigModule implementation", e);
          }
  
          Object module;
          try {
              module = clazz.newInstance();
          } catch (InstantiationException e) {
              throw new RuntimeException("Unable to instantiate ConfigModule implementation for " + clazz, e);
          } catch (IllegalAccessException e) {
              throw new RuntimeException("Unable to instantiate ConfigModule implementation for " + clazz, e);
          }
  
          if (!(module instanceof ConfigModule)) {
              throw new RuntimeException("Expected instanceof ConfigModule, but found: " + module);
          }
          return (ConfigModule) module;
      }
  }