All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.facebook.react.bridge.ModuleSpec Maven / Gradle / Ivy

There is a newer version: 0.52.u
Show newest version
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package com.facebook.react.bridge;

import javax.annotation.Nullable;
import javax.inject.Provider;

import java.lang.reflect.Constructor;

import com.facebook.react.common.build.ReactBuildConfig;

/**
 * A specification for a native module. This exists so that we don't have to pay the cost
 * for creation until/if the module is used.
 *
 * If your module either has a default constructor or one taking ReactApplicationContext you can use
 * {@link #simple(Class)} or {@link #simple(Class, ReactApplicationContext)}} methods.
 */
public class ModuleSpec {
  private static final Class[] EMPTY_SIGNATURE = {};
  private static final Class[] CONTEXT_SIGNATURE = { ReactApplicationContext.class };

  private final Class mType;
  private final Provider mProvider;

  /**
   * Simple spec for modules with a default constructor.
   */
  public static ModuleSpec simple(final Class type) {
    return new ModuleSpec(type, new ConstructorProvider(type, EMPTY_SIGNATURE) {
      @Override
      public NativeModule get() {
        try {
          return getConstructor(type, EMPTY_SIGNATURE).newInstance();
        } catch (Exception e) {
          throw new RuntimeException("ModuleSpec with class: " + type.getName(), e);
        }
      }
    });
  }

  /**
   * Simple spec for modules with a constructor taking ReactApplicationContext.
   */
  public static ModuleSpec simple(
      final Class type,
      final ReactApplicationContext context) {
    return new ModuleSpec(type, new ConstructorProvider(type, CONTEXT_SIGNATURE) {
      @Override
      public NativeModule get() {
        try {
          return getConstructor(type, CONTEXT_SIGNATURE).newInstance(context);
        } catch (Exception e) {
          throw new RuntimeException("ModuleSpec with class: " + type.getName(), e);
        }
      }
    });
  }

  public ModuleSpec(Class type, Provider provider) {
    mType = type;
    mProvider = provider;
  }

  public Class getType() {
    return mType;
  }

  public Provider getProvider() {
    return mProvider;
  }

  private static abstract class ConstructorProvider implements Provider {
    protected @Nullable Constructor mConstructor;

    public ConstructorProvider(Class type, Class[] signature) {
      if (ReactBuildConfig.DEBUG) {
        try {
          mConstructor = getConstructor(type, signature);
        } catch (NoSuchMethodException e) {
          throw new IllegalArgumentException("No such constructor", e);
        }
      }
    }

    protected Constructor getConstructor(
        Class mType,
        Class[] signature) throws NoSuchMethodException {
      if (mConstructor != null) {
        return mConstructor;
      } else {
        return mType.getConstructor(signature);
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy