Home | Table of Contents | CustomJavaReader | CloverETL 4.6.1
--- | --- | ---
Prev | Readers | Next

## CustomJavaReader

# Available in Community Designer

Short Description
Ports
Metadata
CustomJavaReader Attributes
Details
Examples
Best Practices
Compatibility
See also

### Short Description

CustomJavaReader executes user-defined Java code.

Component | Same input metadata | Sorted inputs | Inputs | Outputs | Each to all outputs | Java | CTL | Auto-propagated metadata
--- | --- | --- | --- | --- | --- | --- | --- | ---
CustomJavaReader | - | - | 0-n | 0-n | - |  |  |

### Icon

### Ports

Number of ports depends on the java code.

### Metadata

CustomJavaReader does not propagate metadata.

CustomJavaReader has no metadata templates.

Requirements on metadata depend on user-defined transformation.

### CustomJavaReader Attributes

Attribute | Req | Description | Possible values
--- | --- | --- | ---
Basic
Algorithm | [1] | Runnable transformation in Java defined in the graph. |
Algorithm URL | [1] | External file defining the runnable transformation in Java. |
Algorithm class | [1] | External runnable transformation class. |
Algorithm source charset |  | Encoding of external file defining the transformation. The default encoding depends on DEFAULT_SOURCE_CODE_CHARSET in defaultProperties. | E.g. UTF-8
[1] One of these must be set. These transformation attributes must be specified.

### Details

CustomJavaReader executes Java transformation. CustomJavaReader is a more specific CustomJavaComponent and it is focused on reading data.

There are other similar java components: CustomJavaWriter, CustomJavaTransformer and CustomJavaComponent. All these components use transformation defined in java, they differ in templates being used.

You can use Public Clover API in this component. Documentation on general parts of custom java components and Public Clover API is described in CustomJavaComponent.

#### Java Interfaces for CustomJavaReader

Transformation required by the component must extend `org.jetel.component.AbstractGenericTransform` class.

The component has same java interface as CustomJavaComponent, but it provides different java template. See Java Interfaces for CustomJavaComponent.

### Examples

Generating Random Bytes
Reading Records with Header and Variable-length Field

#### Generating Random Bytes

Generate user-defined number of sequences of random bytes, each sequence is of 32 bytes.

##### Solution

Use CustomJavaReader to create a new user-defined component.

Add new custom attribute RecordCount to the component and set up a value to the attribute, e.g. to 5.

Define the transformation.

    package jk;

    import java.security.SecureRandom;
    import org.jetel.component.AbstractGenericTransform;
    import org.jetel.data.DataRecord;

    /**
     * This is an example custom reader. It shows how you can create records using a
     * data source.
     */
    public class CustomJavaReaderExample01 extends AbstractGenericTransform {

    	@Override
    	public void execute() {
    		Integer recordCount = getProperties().getIntProperty("RecordCount");

    		// Output record prepared for writing to output port 0.
    		DataRecord record = outRecords[0];

    		SecureRandom secureRandom = new SecureRandom();

    		for (int i = 0; i < recordCount; ++i) {
    			byte[] b = new byte[32];

    			secureRandom.nextBytes(b);
    			record.getField("field1").setValue(b);
    			writeRecordToPort(0, record);
    			record.reset();
    		}
    	}
    }

Metadata on output port have need to have one field named field1. The field has byte data type.

#### Reading Records with Header and Variable-length Field

Read binary data from a file. Each record has one byte header and variable length payload. The length of payload is defined by integer value of the header. Read length and payload from ech record. File to be read has to be configured by component attribute.

Example of source data:

    !123456789012345678901234567890123"abcdefghijklmnopqrstuvwxyz78901234

##### Solution

Add attribute FileUrl to the component.

    package jk;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;

    import org.jetel.component.AbstractGenericTransform;
    import org.jetel.data.DataRecord;
    import org.jetel.exception.JetelRuntimeException;

    /**
     * This is an example custom reader. It shows how you can read data from file
     * with specific format.
     */
    public class CustomJavaReaderExample02 extends AbstractGenericTransform {

    	@Override
    	public void execute() {
    		DataRecord record = outRecords[0];
    		String fileUrl = getProperties().getStringProperty("FileUrl");
    		File file = getFile(fileUrl);

    		try (FileInputStream inputStream = new FileInputStream(file)) {
    			for (int length = inputStream.read(); length > 0; length = inputStream.read()) {
    				byte[] b = new byte[length];
    				inputStream.read(b, 0, length);

    				record.getField("field1").setValue(length);
    				record.getField("field2").setValue(b);
    				writeRecordToPort(0, record);
    				record.reset();
    			}
    		} catch (IOException e) {
    			throw new JetelRuntimeException(e);
    		}
    	}
    }

Note: input data is in binary format. First header contains character `!` which corresponds to value `33`. Thirty-three characters follow. Header of second record has value `34` which is displayed as character `"`. Thirty-four bytes follow.

Metadata on output port have need to have two fields named field1 and field2 with types integer and byte.

### Best Practices

If Algorithm URL attribute is used, we recommend users to explicitly specify Algorithm source charset.

### Compatibility

CustomJavaReader is available since CloverETL 4.1.0-M1.

### See also

CustomJavaComponent
CustomJavaWriter
CustomJavaTransformer
Common Properties of Components
Specific Attribute Types
Others Comparison

Prev | Up | Next
ComplexDataReader | Home | Table of Contents | DataGenerator