/* * Copyright 2013 Cloudera 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 org.kitesdk.cli.commands; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import java.io.IOException; import java.util.List; import org.apache.avro.Schema; import org.kitesdk.data.spi.Compatibility; import org.kitesdk.data.spi.SchemaUtil; import org.slf4j.Logger; @Parameters(commandDescription = "Show the schema for a Dataset") public class SchemaCommand extends BaseDatasetCommand { @Parameter(description = "<dataset name>") List<String> datasets; @edu.umd.cs.findbugs.annotations.SuppressWarnings( value="UWF_NULL_FIELD", justification = "Field set by JCommander") @Parameter(names={"-o", "--output"}, description="Save schema avsc to path") String outputPath = null; @Parameter(names="--minimize", description="Minimize schema file size by eliminating white space") boolean minimize=false; @Parameter(names="--merge", description="Merge schemas into a single output schema") boolean merge=false; public SchemaCommand(Logger console) { super(console); } @Override @edu.umd.cs.findbugs.annotations.SuppressWarnings( value={"NP_GUARANTEED_DEREF", "NP_NULL_ON_SOME_PATH"}, justification="Null case checked by precondition") public int run() throws IOException { Preconditions.checkArgument( datasets != null && !datasets.isEmpty(), "Missing dataset name"); if (merge || datasets.size() == 1) { Schema mergedSchema = null; for (String uriOrPath : datasets) { mergedSchema = merge(mergedSchema, schema(uriOrPath)); } Preconditions.checkNotNull(mergedSchema, "No valid schema found"); output(mergedSchema.toString(!minimize), console, outputPath); } else { Preconditions.checkArgument(outputPath == null, "Cannot output multiple schemas to one file"); for (String name : datasets) { console.info("Dataset \"{}\" schema: {}", name, schema(name).toString(!minimize)); } } return 0; } @Override public List<String> getExamples() { return Lists.newArrayList( "# Print the schema for dataset \"users\" to standard out:", "users", "# Print the schema for a dataset URI to standard out:", "dataset:hbase:zk1,zk2/users", "# Save the schema for dataset \"users\" to user.avsc:", "users -o user.avsc" ); } private Schema schema(String uriOrPath) throws IOException { if (!isDatasetOrViewUri(uriOrPath) && !Compatibility.isCompatibleName(uriOrPath)) { return new Schema.Parser().parse(open(uriOrPath)); } else { return load(uriOrPath, Object.class) .getDataset().getDescriptor().getSchema(); } } private static Schema merge(Schema left, Schema right) { if (left == null) { return right; } else if (right == null) { return left; } else { return SchemaUtil.merge(left, right); } } }