Skip to content

Commit

Permalink
Adding JSON Iterator and removing unnecessary imports
Browse files Browse the repository at this point in the history
  • Loading branch information
SriramKeerthi committed Nov 27, 2016
1 parent a08013f commit 94bc0a7
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class JsonFileReader {
* @return List of JSON lines from the file
* @throws IOException thrown if there is a problem accessing the file
*/
public static List<Map<String, Object>> readJsonFromResource(String resourceName) throws IOException {
public static List<Map<String, Object>> readJsonFromResource(final String resourceName) throws IOException {
List<Map<String, Object>> jsonList = new ArrayList<>();
String json;
try (BufferedReader br = new BufferedReader(
Expand All @@ -46,7 +46,7 @@ public static List<Map<String, Object>> readJsonFromResource(String resourceName
* @return List of JSON lines from the file
* @throws IOException thrown if there is a problem accessing the file
*/
public static List<Map<String, Object>> readJsonFromFile(String fileName) throws IOException {
public static List<Map<String, Object>> readJsonFromFile(final String fileName) throws IOException {
List<Map<String, Object>> jsonList = new ArrayList<>();
for (String json : getFileLines(fileName)) {
jsonList.add(gson.fromJson(json, HashMap.class));
Expand All @@ -61,7 +61,7 @@ public static List<Map<String, Object>> readJsonFromFile(String fileName) throws
* @return List of lines from the file
* @throws IOException thrown if there is a problem accessing the file
*/
public static List<String> getFileLines(String fileName) throws IOException {
public static List<String> getFileLines(final String fileName) throws IOException {
List<String> text = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.caffinc.jaggr.utils;

import com.google.gson.Gson;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;

/**
* Iterates a JSON file
*
* @author Sriram
* @since 11/27/2016
*/
public class JsonIterator implements Iterator<Map<String, Object>>, Closeable {
private final BufferedReader bufferedReader;
private String cachedLine;
private boolean finished = false;
private Gson gson = new Gson();

/**
* Constructs an iterator of the lines for a <code>fileName</code>.
*
* @param fileName the <code>fileName</code> to read from
* @throws IOException thrown if there is a problem accessing the file
*/
public JsonIterator(final String fileName) throws IOException {
this(new BufferedReader(new FileReader(fileName)));
}

/**
* Constructs an iterator of the lines for a <code>Reader</code>.
*
* @param reader the <code>Reader</code> to read from, not null
* @throws IllegalArgumentException if the reader is null
*/
public JsonIterator(final Reader reader) throws IllegalArgumentException {
if (reader == null) {
throw new IllegalArgumentException("Reader must not be null");
}
if (reader instanceof BufferedReader) {
bufferedReader = (BufferedReader) reader;
} else {
bufferedReader = new BufferedReader(reader);
}
}

/**
* Indicates whether the <code>Reader</code> has more lines.
* If there is an <code>IOException</code> then {@link #close()} will
* be called on this instance.
*
* @return {@code true} if the Reader has more lines
* @throws IllegalStateException if an IO exception occurs
*/
public boolean hasNext() {
if (cachedLine != null) {
return true;
} else if (finished) {
return false;
} else {
try {
while (true) {
final String line = bufferedReader.readLine();
if (line == null) {
finished = true;
return false;
}
cachedLine = line;
return true;
}
} catch (final IOException ioe) {
close();
throw new IllegalStateException(ioe);
}
}
}

/**
* Returns the next object in the file or wrapped <code>Reader</code>.
*
* @return the next JSON object from the input
* @throws NoSuchElementException if there is no object to return
*/
public Map<String, Object> next() {
return nextObject();
}

/**
* Returns the next object in the file or wrapped <code>Reader</code>.
*
* @return the next JSON object from the input
* @throws NoSuchElementException if there is no object to return
*/
public Map<String, Object> nextObject() {
if (!hasNext()) {
throw new NoSuchElementException("No more objects");
}
final String currentLine = cachedLine;
cachedLine = null;
return gson.fromJson(currentLine, HashMap.class);
}

/**
* Closes the underlying <code>Reader</code> quietly.
* This method is useful if you only want to process the first few
* lines of a larger file. If you do not close the iterator
* then the <code>Reader</code> remains open.
* This method can safely be called multiple times.
*/
public void close() {
finished = true;
try {
bufferedReader.close();
} catch (final IOException ioe) {
// ignore
}
cachedLine = null;
}

/**
* Unsupported.
*
* @throws UnsupportedOperationException always
*/
public void remove() {
throw new UnsupportedOperationException("Remove unsupported on JsonIterator");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.caffinc.jaggr.utils;

import com.google.gson.Gson;
import org.junit.Assert;
import org.junit.Test;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
* Tests for the JsonIterator
*
* @author Sriram
* @since 11/27/2016
*/
public class JsonIteratorTest {
private static final String TEMP_DIR = System.getProperty("java.io.tmpdir");
private static final Random RANDOM = new Random();
private static final Gson GSON = new Gson();

@Test
public void testJsonFileIterator() throws Exception {
Path tempFilePath = Paths.get(TEMP_DIR, "jsontest" + RANDOM.nextInt() + ".json");
try {
List<Map<String, Object>> expectedData = new ArrayList<>();
try (BufferedWriter br = new BufferedWriter(new FileWriter(tempFilePath.toFile()))
) {
for (int i = 0; i < 10; i++) {
Map<String, Object> json = new HashMap<>();
json.put("_id", (double) i);
json.put("val", RANDOM.nextDouble());
expectedData.add(json);
br.write(GSON.toJson(json) + "\n");
}
}
try (JsonIterator jsonIterator = new JsonIterator(tempFilePath.toString())) {
for (Map<String, Object> expected : expectedData) {
Map<String, Object> actual = jsonIterator.next();
Assert.assertEquals("Value should match value written to file", expected, actual);
}
}
} finally {
Files.delete(tempFilePath);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ public List<Map<String, Object>> aggregate(Iterator<Map<String, Object>> objectI
}

/**
* Aggregates over a list of JSON Objects
* Aggregates over an iterable list of JSON Objects
*
* @param objectList JSON Object list
* @param objectList Iterable list of JSON Objects
* @return aggregation result
*/
public List<Map<String, Object>> aggregate(List<Map<String, Object>> objectList) {
public List<Map<String, Object>> aggregate(Iterable<Map<String, Object>> objectList) {
Map<String, Map<String, Object>> workspace = new HashMap<>();
if (objectList != null) {
for (Map<String, Object> object : objectList) {
Expand Down

0 comments on commit 94bc0a7

Please sign in to comment.