// Path: src/main/java/net/jgp/labs/spark/x/utils/DataframeUtils.java
// public class DataframeUtils {
// 
//   public static Dataset<Row> addMetadata(Dataset<Row> df, String colName,
//       String key, String value) {
//     Metadata metadata = new MetadataBuilder()
//         .withMetadata(ColumnUtils.getMetadata(df, colName))
//         .putString(key, value)
//         .build();
//     Column col = col(colName);
//     return df.withColumn(colName, col, metadata);
//   }
// 
//   public static Dataset<Row> addMetadata(Dataset<Row> df, String key,
//       String value) {
//     for (String colName : df.columns()) {
//       df = addMetadata(df, colName, key, value);
//     }
//     return df;
//   }
// 
// }
// 
// Path: src/main/java/net/jgp/labs/spark/x/utils/FieldUtils.java
// public class FieldUtils {
// 
//   public static String explain(StructField field) {
//     StringBuilder sb = new StringBuilder();
// 
//     sb.append("Name ....... ");
//     sb.append(field.name());
//     sb.append("\nMetadata ... ");
//     sb.append(field.metadata());
//     sb.append("\nType ....... ");
//     sb.append(field.dataType());
// 
//     return sb.toString();
//   }
// 
// }


import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.sql.types.StructField;
import net.jgp.labs.spark.x.utils.DataframeUtils;
import net.jgp.labs.spark.x.utils.FieldUtils;
package net.jgp.labs.spark.l090_metadata.l100_join_metadata;



public class AddAuthorsAndBooksMetadataApp {

  public static void main(String[] args) {
    AddAuthorsAndBooksMetadataApp app = new AddAuthorsAndBooksMetadataApp();
    app.start();
  }

  private void start() {
    SparkSession spark = SparkSession.builder()
// Path: src/main/java/net/jgp/labs/spark/x/utils/DataframeUtils.java
// public class DataframeUtils {
// 
//   public static Dataset<Row> addMetadata(Dataset<Row> df, String colName,
//       String key, String value) {
//     Metadata metadata = new MetadataBuilder()
//         .withMetadata(ColumnUtils.getMetadata(df, colName))
//         .putString(key, value)
//         .build();
//     Column col = col(colName);
//     return df.withColumn(colName, col, metadata);
//   }
// 
//   public static Dataset<Row> addMetadata(Dataset<Row> df, String key,
//       String value) {
//     for (String colName : df.columns()) {
//       df = addMetadata(df, colName, key, value);
//     }
//     return df;
//   }
// 
// }
// 
// Path: src/main/java/net/jgp/labs/spark/x/utils/FieldUtils.java
// public class FieldUtils {
// 
//   public static String explain(StructField field) {
//     StringBuilder sb = new StringBuilder();
// 
//     sb.append("Name ....... ");
//     sb.append(field.name());
//     sb.append("\nMetadata ... ");
//     sb.append(field.metadata());
//     sb.append("\nType ....... ");
//     sb.append(field.dataType());
// 
//     return sb.toString();
//   }
// 
// }


// Path: src/main/java/net/jgp/labs/spark/l090_metadata/l100_join_metadata/AddAuthorsAndBooksMetadataApp.java
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.sql.types.StructField;
import net.jgp.labs.spark.x.utils.DataframeUtils;
import net.jgp.labs.spark.x.utils.FieldUtils;

package net.jgp.labs.spark.l090_metadata.l100_join_metadata;



public class AddAuthorsAndBooksMetadataApp {

  public static void main(String[] args) {
    AddAuthorsAndBooksMetadataApp app = new AddAuthorsAndBooksMetadataApp();
    app.start();
  }

  private void start() {
    SparkSession spark = SparkSession.builder()
        .appName("Authors and Books metadata")