Repository: jtablesaw/tablesaw
Pull request #701 (2019-10-29 20:30:35)

Made two FileReader methods public (and changed their names for clarity)
These methods make it possible for users to get the inferred column types and the column names for a data file.

Having this metadata can simplify the solution to some specialized automated file reading issues. .

Thanks for contributing.

- [x] Tick to sign-off your agreement to the [Developer Certificate of Origin (DCO) 1.1](https://developercertificate.org)

## Description

loosened the access control and renaming of two previously hidden methods. 

## Testing

Did you add a unit test?
no


Patch:
diff --git a/core/src/main/java/tech/tablesaw/io/FileReader.java b/core/src/main/java/tech/tablesaw/io/FileReader.java
index 82366e18..ab7a04ff 100644
--- a/core/src/main/java/tech/tablesaw/io/FileReader.java
+++ b/core/src/main/java/tech/tablesaw/io/FileReader.java
@@ -21,7 +21,11 @@ public abstract class FileReader {
   /** Constructs a CsvReader */
   public FileReader() {}
 
-  protected ColumnType[] getTypes(
+  /**
+   * Returns an array containing the inferred columnTypes for the file being read, as calculated by
+   * the ColumnType inference logic. These types may not be correct.
+   */
+  public ColumnType[] getColumnTypes(
       Reader reader, ReadOptions options, int linesToSkip, AbstractParser<?> parser) {
 
     parser.beginParsing(reader);
@@ -56,7 +60,8 @@ public abstract class FileReader {
     return name.trim();
   }
 
-  private String[] getHeaderNames(
+  /** Returns the column names for each column in the source. */
+  public String[] getColumnNames(
       ReadOptions options, ColumnType[] types, AbstractParser<?> parser) {
     if (options.header()) {
       String[] headerNames = parser.parseNext();
@@ -88,7 +93,7 @@ public abstract class FileReader {
     parser.beginParsing(reader);
     Table table = Table.create(options.tableName());
 
-    List<String> headerRow = Lists.newArrayList(getHeaderNames(options, types, parser));
+    List<String> headerRow = Lists.newArrayList(getColumnNames(options, types, parser));
 
     for (int x = 0; x < types.length; x++) {
       if (types[x] != SKIP) {
diff --git a/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java b/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
index 1ec21f81..29209618 100644
--- a/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
+++ b/core/src/main/java/tech/tablesaw/io/csv/CsvReader.java
@@ -137,7 +137,7 @@ public class CsvReader extends FileReader implements DataReader<CsvReadOptions>
     CsvParser parser = csvParser(options);
 
     try {
-      return getTypes(reader, options, linesToSkip, parser);
+      return getColumnTypes(reader, options, linesToSkip, parser);
     } finally {
       parser.stopParsing();
       // we don't close the reader since we didn't create it
diff --git a/core/src/main/java/tech/tablesaw/io/fixed/FixedWidthReader.java b/core/src/main/java/tech/tablesaw/io/fixed/FixedWidthReader.java
index 28dee235..6ff6a490 100644
--- a/core/src/main/java/tech/tablesaw/io/fixed/FixedWidthReader.java
+++ b/core/src/main/java/tech/tablesaw/io/fixed/FixedWidthReader.java
@@ -138,7 +138,7 @@ public class FixedWidthReader extends FileReader implements DataReader<FixedWidt
     AbstractParser<?> parser = fixedWidthParser(options);
 
     try {
-      return getTypes(reader, options, linesToSkip, parser);
+      return getColumnTypes(reader, options, linesToSkip, parser);
     } finally {
       parser.stopParsing();
       // we don't close the reader since we didn't create it
diff --git a/html/src/main/java/tech/tablesaw/io/html/HtmlReader.java b/html/src/main/java/tech/tablesaw/io/html/HtmlReader.java
index be80cab3..de351e7f 100644
--- a/html/src/main/java/tech/tablesaw/io/html/HtmlReader.java
+++ b/html/src/main/java/tech/tablesaw/io/html/HtmlReader.java
@@ -52,7 +52,9 @@ public class HtmlReader implements DataReader<HtmlReadOptions> {
               "Table index outside bounds. The URL has " + tables.size() + " tables");
         }
       } else {
-          throw new IllegalStateException(tables.size() + " tables found. When more than one html table is present on the page you must specify the index of the table to read from.");
+        throw new IllegalStateException(
+            tables.size()
+                + " tables found. When more than one html table is present on the page you must specify the index of the table to read from.");
       }
     }
     Element htmlTable = tables.get(tableIndex);
diff --git a/jsplot/src/main/java/tech/tablesaw/plotly/Utils.java b/jsplot/src/main/java/tech/tablesaw/plotly/Utils.java
index 3267a0e6..a9fafec8 100644
--- a/jsplot/src/main/java/tech/tablesaw/plotly/Utils.java
+++ b/jsplot/src/main/java/tech/tablesaw/plotly/Utils.java
@@ -8,16 +8,22 @@ public class Utils {
     return Arrays.toString(data);
   }
 
+  /** @return un-escaped quote of argument */
   public static String quote(String string) {
     return "'" + string + "'";
   }
 
+  private static String escape(String s) {
+    return s.replaceAll("\\'", "\\\\'");
+  }
+
+  /** @return a Javascript array of strings (escaped if needed) */
   public static String dataAsString(Object[] data) {
     StringBuilder builder = new StringBuilder("[");
     for (int i = 0; i < data.length; i++) {
       Object o = data[i];
       builder.append("'");
-      builder.append(o);
+      builder.append(escape(String.valueOf(o)));
       builder.append("'");
       if (i < data.length - 1) {
         builder.append(",");


Test patch:
diff --git a/jsplot/src/test/java/tech/tablesaw/plotly/UtilsTest.java b/jsplot/src/test/java/tech/tablesaw/plotly/UtilsTest.java
new file mode 100644
index 00000000..6c7b2ef5
--- /dev/null
+++ b/jsplot/src/test/java/tech/tablesaw/plotly/UtilsTest.java
@@ -0,0 +1,13 @@
+package tech.tablesaw.plotly;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.Test;
+
+public class UtilsTest {
+
+  @Test
+  public void testEscapeQuote() {
+    String s = Utils.dataAsString(new String[] {"Bobby's tables"});
+    assertTrue(s.contains("\\"));
+  }
+}