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);
}
}
});
}
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;
}
Aggregations