Tuesday, September 2, 2008

Implementing your own encoder in the Encoder Tool - Part 2

I the previous post I have explained how to create a custom encoder. The encoder that takes input and encodes it to output. But what happens, if the encoder needs an additional input to perform an encoding? E.g. the Inflate/Deflate encoders needs to know if they need to use gzip. The Digital Signatures encoders need access to the key stores with the keys and so on.
So how can the encoder receive the additional input?

Actually I tried to do it as simple as I could. To tell the Encoder Tool that your encoder needs input, you'll need to annotate the field with the InputField annotation.
So the Encoder Tool will know that prior to performing the actual encoding, it should pop-up the input dialog, get the input from user and populate the fields.

Let's take a look on the example:
package tarlog.encoder.tool.encoders;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;

import tarlog.encoder.tool.api.AbstractEncoder;
import tarlog.encoder.tool.api.fields.InputField;

public class DeflateEncoder extends AbstractEncoder {

@InputField(name = "GZIP compatible compression")
private boolean nowrap = true;

public Object encode(byte[] source) {

try {
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
Deflater deflater = new Deflater(Deflater.DEFLATED, nowrap);
DeflaterOutputStream deflaterStream = new DeflaterOutputStream(
bytesOut, deflater);
return bytesOut.toByteArray();
} catch (IOException e) {
return null;

The field nowrap is annotated with the InputField. So when the user invokes the encoder, the following dialog will pop-up:

I guess that the idea is clear. So let's just mention what java types are supported as input fields:
  • String - can be a single line, a text box or a combo box. See TextField annotation for more details.
  • Boolean - check box
  • Integer - spinner
  • Enum - combo box
  • File - input dialog for a file or a directory. See InputFileField and InputDirectoryField annoations for more details.
  • Properties - table of properties
  • Arrays - list. See InputListField for more details.

The input dialog supports on going validations. To do so, the encoder must implement the tarlog.encoder.tool.api.fields.Validator interface. Let's take a look on the example:

public class X509CertificateEncoder extends AbstractEncoder implements
Validator {

private X509Certificate cert;

@InputField(name = "Certificate File", order = -300)
private File file;

@InputField(name = "Algorithm", readonly = true)
private SignatureAlgorithms algorithm = SignatureAlgorithms.SHA1withDSA;

@InputField(name = "Signature")
@InputTextField(multiline = true)
private String signature;

public String isValid() {
if (file == null || file.equals("")) {
return "Certificate File cannot be empty";
if (signature == null || signature.equals("")) {
return "Signature cannot be empty";
return null;


The method isValid() will be invoked each time the user changes input.

No comments: