Writing your own sources

This section provides instructions on how to develop your own Transform4J Data Sources. I'm going to use the Transform4J JsonDataSource as an example.

Data sources implement interface TransformerDataSource. Data sources implement three methods: init(), next(), and close. The first, init() provides developers a chance to initialize and resources needed for performing reads. The second, next() will be called for each record of data produced. Return null when end-of-data is reached. The last, close is guaranteed to be called; this provides developers a chance to terminate any resources that are allocated for performing reads.

Let's go through this step-by-step. First, create a class that implements interface TransformerDataSource.

public class JsonDataSource implements TransformerDataSource<DataRecord> {
	@Override
	public void init() {
	}
	
	@Override
	public DataRecord next() {
	}
	
	@Override
	public void close() {
	}
}
			

This data source requires an InputStream as input. Adding a field and accessor/mutator methods:

public class JsonDataSource implements TransformerDataSource<DataRecord> {
	private BufferedInputStream jsonInputStream;
	
	public InputStream getJsonInputStream() {
		return jsonInputStream;
	}
	
	public void setJsonInputStream(InputStream jsonData) {
		this.jsonInputStream = new BufferedInputStream(jsonData, 8192);;
	}
}
			

Do any setup work in init(). JsonDataSource uses Gson underneath, which requires some setup.

public class JsonDataSource implements TransformerDataSource<DataRecord> {

	private JsonReader reader;
	private Gson gson;

	@Override
	public void init() {
		try {
			reader = new JsonReader(new InputStreamReader(jsonInputStream, "UTF-8"));
			reader.beginArray();
		} catch (Exception e) {
			throw new Transform4jRuntimeException("Error reading Json input stream", e);
		}
		
		GsonBuilder builder = new GsonBuilder();
		builder.registerTypeHierarchyAdapter(DataRecord.class, new DataRecordGsonDeserializer());
		builder.setPrettyPrinting();
		gson = builder.create();
			
	}
}
			

Insert logic to process all input records:

public class JsonDataSource implements TransformerDataSource<DataRecord> {
	@Override
	public DataRecord next() {
		try {
			if (reader.hasNext()) {
				return (DataRecord)gson.fromJson(reader, DataRecord.class);
			}
			return null;
		} catch (Exception e) {
			throw new Transform4jRuntimeException("Error reading next DataRecord Json input stream", e);
		} 
	}
}
			

Insert logic to write any unwritten data and close all resources:

public class JsonDataSource implements TransformerDataSource<DataRecord> {
	@Override
	public void close() {
		try {
			reader.endArray();
			reader.close();
		} catch (Exception e) {
			throw new Transform4jRuntimeException("Error closing Json input stream", e);
		}
		
	}
}
			

See TransformerDataSource javadoc.