Search in sources :

Example 1 with EmbeddedDataset

use of co.cask.cdap.api.dataset.module.EmbeddedDataset in project cdap by caskdata.

the class SingleTypeModule method register.

@Override
public void register(DatasetDefinitionRegistry registry) {
    final Constructor ctor = findSuitableCtorOrFail(dataSetClass);
    DatasetType typeAnn = dataSetClass.getAnnotation(DatasetType.class);
    // default type name to dataset class name
    String typeName = typeAnn != null ? typeAnn.value() : dataSetClass.getName();
    // The ordering is important. It is the same order as the parameters
    final Map<String, DatasetDefinition> embeddedDefinitions = Maps.newLinkedHashMap();
    final Class<?>[] paramTypes = ctor.getParameterTypes();
    Annotation[][] paramAnns = ctor.getParameterAnnotations();
    // Gather all dataset name and type information for the @EmbeddedDataset parameters
    for (int i = 1; i < paramTypes.length; i++) {
        // Must have the EmbeddedDataset as it's the contract of the findSuitableCtorOrFail method
        EmbeddedDataset anno = Iterables.filter(Arrays.asList(paramAnns[i]), EmbeddedDataset.class).iterator().next();
        String type = anno.type();
        // default to dataset class name if dataset type name is not specified through the annotation
        if (EmbeddedDataset.DEFAULT_TYPE_NAME.equals(type)) {
            type = paramTypes[i].getName();
        }
        DatasetDefinition embeddedDefinition = registry.get(type);
        if (embeddedDefinition == null) {
            throw new IllegalStateException(String.format("Unknown Dataset type '%s', specified by parameter number %d of the %s Dataset", type, i, dataSetClass.getName()));
        }
        embeddedDefinitions.put(anno.value(), embeddedDefinition);
    }
    registry.add(new CompositeDatasetDefinition<Dataset>(typeName, embeddedDefinitions) {

        @Override
        public Dataset getDataset(DatasetContext datasetContext, DatasetSpecification spec, Map<String, String> arguments, ClassLoader classLoader) throws IOException {
            List<Object> params = new ArrayList<>();
            params.add(spec);
            for (Map.Entry<String, DatasetDefinition> entry : embeddedDefinitions.entrySet()) {
                params.add(entry.getValue().getDataset(datasetContext, spec.getSpecification(entry.getKey()), arguments, classLoader));
            }
            try {
                return (Dataset) ctor.newInstance(params.toArray());
            } catch (Exception e) {
                throw Throwables.propagate(e);
            }
        }
    });
}
Also used : EmbeddedDataset(co.cask.cdap.api.dataset.module.EmbeddedDataset) Constructor(java.lang.reflect.Constructor) EmbeddedDataset(co.cask.cdap.api.dataset.module.EmbeddedDataset) Dataset(co.cask.cdap.api.dataset.Dataset) DatasetSpecification(co.cask.cdap.api.dataset.DatasetSpecification) DatasetType(co.cask.cdap.api.dataset.module.DatasetType) IOException(java.io.IOException) DatasetDefinition(co.cask.cdap.api.dataset.DatasetDefinition) CompositeDatasetDefinition(co.cask.cdap.api.dataset.lib.CompositeDatasetDefinition) IOException(java.io.IOException) ArrayList(java.util.ArrayList) List(java.util.List) DatasetContext(co.cask.cdap.api.dataset.DatasetContext)

Example 2 with EmbeddedDataset

use of co.cask.cdap.api.dataset.module.EmbeddedDataset in project cdap by caskdata.

the class SingleTypeModule method findSuitableCtorOrFail.

/**
   * Find a {@link Constructor} of the given {@link Dataset} class that the first parameter is of type
   * {@link DatasetSpecification} and the rest parameters are of type {@link Dataset} and are annotated with
   * {@link EmbeddedDataset}.
   *
   * @param dataSetClass The class to search for the constructor
   * @return the {@link Constructor} found
   * @throws IllegalArgumentException if the given class doesn't contain the constructor this method is looking for
   */
@VisibleForTesting
static Constructor findSuitableCtorOrFail(Class<? extends Dataset> dataSetClass) {
    Constructor suitableCtor = null;
    for (Constructor ctor : dataSetClass.getConstructors()) {
        Class<?>[] paramTypes = ctor.getParameterTypes();
        // Ignore constructor that has no-arg or the first arg is not DatasetSpecification
        if (paramTypes.length <= 0 || !DatasetSpecification.class.isAssignableFrom(paramTypes[0])) {
            continue;
        }
        Annotation[][] paramAnns = ctor.getParameterAnnotations();
        boolean otherParamsAreDatasets = true;
        // All parameters must be of Dataset type and annotated with EmbeddedDataset
        for (int i = 1; i < paramTypes.length; i++) {
            if (!Dataset.class.isAssignableFrom(paramTypes[i]) || !Iterables.any(Arrays.asList(paramAnns[i]), Predicates.instanceOf(EmbeddedDataset.class))) {
                otherParamsAreDatasets = false;
                break;
            }
        }
        if (!otherParamsAreDatasets) {
            continue;
        }
        if (suitableCtor != null) {
            throw new IllegalArgumentException(String.format("Dataset class %s must have single constructor with parameter types of" + " (DatasetSpecification, [0..n] @EmbeddedDataset Dataset) ", dataSetClass));
        }
        suitableCtor = ctor;
    }
    if (suitableCtor == null) {
        throw new IllegalArgumentException(String.format("Dataset class %s must have single constructor with parameter types of" + " (DatasetSpecification, [0..n] @EmbeddedDataset Dataset) ", dataSetClass));
    }
    return suitableCtor;
}
Also used : EmbeddedDataset(co.cask.cdap.api.dataset.module.EmbeddedDataset) Constructor(java.lang.reflect.Constructor) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

EmbeddedDataset (co.cask.cdap.api.dataset.module.EmbeddedDataset)2 Constructor (java.lang.reflect.Constructor)2 Dataset (co.cask.cdap.api.dataset.Dataset)1 DatasetContext (co.cask.cdap.api.dataset.DatasetContext)1 DatasetDefinition (co.cask.cdap.api.dataset.DatasetDefinition)1 DatasetSpecification (co.cask.cdap.api.dataset.DatasetSpecification)1 CompositeDatasetDefinition (co.cask.cdap.api.dataset.lib.CompositeDatasetDefinition)1 DatasetType (co.cask.cdap.api.dataset.module.DatasetType)1 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1