/* * Copyright © 2014 Cask Data, Inc. * * 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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 co.cask.cdap.api.dataset.lib; import co.cask.cdap.api.annotation.Beta; import co.cask.cdap.api.dataset.Dataset; import co.cask.cdap.api.dataset.DatasetAdmin; import co.cask.cdap.api.dataset.DatasetContext; import co.cask.cdap.api.dataset.DatasetDefinition; import co.cask.cdap.api.dataset.DatasetProperties; import co.cask.cdap.api.dataset.DatasetSpecification; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Handy implementation of {@link DatasetDefinition} that implements basic methods by delegating logic execution to * underlying dataset definitions. * * @param <D> defines data operations that can be performed on this dataset instance */ @Beta public abstract class CompositeDatasetDefinition<D extends Dataset> extends AbstractDatasetDefinition<D, DatasetAdmin> { private final Map<String, ? extends DatasetDefinition> delegates; /** * Constructor that takes an info about underlying datasets * @param name this dataset type name * @param delegates map of [dataset instance name] -> [dataset definition] to use for this instance name */ protected CompositeDatasetDefinition(String name, Map<String, ? extends DatasetDefinition> delegates) { super(name); this.delegates = delegates; } /** * Gets dataset for underlying dataset instance of given name * @param name dataset instance name * @param type expected type of the dataset * @param spec parent dataset instance name * @param <T> expected type of the dataset * @return dataset to perform data operations * @throws IOException */ @SuppressWarnings("unchecked") protected final <T extends Dataset> T getDataset(DatasetContext datasetContext, String name, Class<T> type, DatasetSpecification spec, Map<String, String> arguments, ClassLoader classLoader) throws IOException { return (T) delegates.get(name).getDataset(datasetContext, spec.getSpecification(name), arguments, classLoader); } @SuppressWarnings("unchecked") protected final <T extends Dataset> T getDataset(DatasetContext datasetContext, String name, DatasetSpecification spec, Map<String, String> arguments, ClassLoader classLoader) throws IOException { // NOTE: by default we propagate properties to the embedded datasets return (T) delegates.get(name).getDataset(datasetContext, spec.getSpecification(name), arguments, classLoader); } @Override public final DatasetSpecification configure(String instanceName, DatasetProperties properties) { List<DatasetSpecification> specs = new ArrayList<>(); for (Map.Entry<String, ? extends DatasetDefinition> impl : this.delegates.entrySet()) { specs.add(impl.getValue().configure(impl.getKey(), properties)); } return DatasetSpecification.builder(instanceName, getName()) .properties(properties.getProperties()) .datasets(specs) .build(); } @Override public final DatasetAdmin getAdmin(DatasetContext datasetContext, DatasetSpecification spec, ClassLoader classLoader) throws IOException { List<DatasetAdmin> admins = new ArrayList<>(); for (Map.Entry<String, ? extends DatasetDefinition> impl : this.delegates.entrySet()) { admins.add(impl.getValue().getAdmin(datasetContext, spec.getSpecification(impl.getKey()), classLoader)); } return new CompositeDatasetAdmin(admins); } }