Please consider the announced discontinuation of the SOAP API. The Java Library will not work after SOAP API is discontinued. There is no replacement of this library intended, as the recommendation for REST is to use e.g. Swagger Codegen or similar generators. With the upcoming REST API v6, the integration in Java will be even easier as we had a focus on compatibility with the OpenAPI Generator.

What the eSAW Java Library is, and what it isn’t

Following eSAW Java Library uses SOAP service endpoints!


The eSAW Java Library is basically a sample code for Java and SOAP calls for the beginning integrating eSignAnyWhere with Java. It is a java library, consisting of java classes that helps java developers to integrate the eSAW API into their Java applications. It’s a wrapper over the API calls which are provided as SOAP service endpoints. The eSAW library also comes with a set of classes which provide methods to configure the API calls in a more comfortable way than direct XML manipulation.

The eSAW Java Library is also sort of demo code which shows how to use our API.

The eSAW Java Library IS NOT seen as full-featured product, and is not part of the commercial products of namirial. The use of this API functionality is on your own risk, without any grants regarding bug fixes etc. The API implementation raises no claim to completeness, but allows multiple levels to get deeper into details.

The eSAW Java Library IS NOT part of a specific eSAW release, and so has an independent version number scheme. It is not part of the release cycles, and cannot be seen as “stable” code. The eSAW Java Library is an evolutionary library and so has to be seen as “in development”. However, you can use the library in production at your own risk. You have to be aware that changes within the library may come up, and that there might me some code maintenance required when using the library and migrating to a newer library version in the future.

Important

The eSignAnyWhere Java Library is considered as sample code for java and as a first-step with eSignAnyWhere API. We do not provide support for the library and we do not guarantee its functionality. Therefore we deliver the source code of the library, so you can adopt and modify the library to your needs.

Download


Here you can download the current version of the eSignAnyWhere Java Library. The library source code is contained in the JAR.

Architecture

There is one SignAnyWhereServer instance which wraps the server calls.

Then, there are two concepts of entity classes:

The configuration wrappers provide getters and setters which allow instantiation and manipulation of the configuration. When using the configuration wrappers, there is no need of (but the ability to) direct XML access for common use cases. These configuration wrappers are used to define configurations from scratch before sending them to the server. These wrappers do in general provide three levels of access:

Note: Some classes are marked as “Prototype”. A prototype is not backed by an XML, so you cannot use the XML access level on …Prototype entity classes.

To manipulate existing XML structures, we have the Adapters. They are simple wrappers on XML elements but do not provide different access levels. Adapters are mostly used on XMLs which were received e.g. as result from a former server call, before using the XML as part of another server call.

Beside the entity concept, there exist Processors which are invoked between a set of server calls, when SOAP API several server calls are composed to one use case method of the SignAnyWhereServer. The processors are set as part of the configuration. Processors get Adapters which can be manipulated by the processor.

Hello World Example

With a simple HelloWorld example, we show how to send a simple PDF file, which does contain “sig strings” to place the signature field, to a recipient. This example, with just 6 instruction lines, shows how easy the simplest use case can be integrated.

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import com.xyzmo.esaw.lib.SAWServerException;
import com.xyzmo.esaw.lib.SignAnyWhereServer;
import com.xyzmo.esaw.lib.paramtypes.Envelope;
import com.xyzmo.esaw.lib.paramtypes.EnvelopeSimple;
import com.xyzmo.esaw.lib.paramtypes.RecipientPrototype;
import com.xyzmo.esaw.lib.paramtypes.RecipientPrototypeSimple;

public class HelloWorldExample {

	/**
	 * The username is the mail address used to log in at the eSignAnyWhere web
	 * ui.
	 */
	private static final String SAW_USERNAME = "your.username@example.com";

	/**
	 * Get the key from Web-UI: [Settings], [Organization], Application Key.
	 * It's an UID with 16 hex digits and some delimiters, something like
	 * "123def78-a23d-5fg8-1234-ef7890abcdef"
	 */
	private static final String SAW_ORGANIZATIONKEY = "123def78-a23d-5fg8-1234-ef7890abcdef";

	private static SignAnyWhereServer server;

	public static void main(String[] args) throws IOException, SAWServerException {
		EnvelopeSimple simpleEnvelope1 = Envelope.createSimple();
		File myContract = new File("C:\\<your-path>\\<your-file>.pdf");
		simpleEnvelope1.addFile(myContract);

		RecipientPrototypeSimple rs1 = RecipientPrototype
			.createSimple("recipient.email@domain.com");

		/*
		 * without specifying the workstep - implies using a new AdHoc workstep.
		 */
		simpleEnvelope1.addWorkstep(rs1);
		server.sendEnvelope(simpleEnvelope1);
	}
}

Simple Use Case

Specify Recipient Name and Workstep Authentication

It’s easy to provide more information about the recipient (e.g. recipient’s name). Just add some lines which set properties of the recipient already created. The web based user interface of our SaaS platform, which could also be used with trial accounts, gives you an idea of some possibilities:

RecipientPrototypeSimple rs3 = RecipientPrototype.createSimple("mike.miller@example.com");
rs3.setFirstName("Mike");
rs3.setLastName("Miller");
rs3.getAdvanced().setAuthentication(RecipientPrototype.AuthenticationMethod.PIN, "1234");

Sequential or Parallel Processing

When using the API, there are more options than provided in the web based user interface. The web based UI allows defining sequential use cases only. With the API, you can also define parallel steps, or a parallel sequence between other sequential steps.

The EnvelopeSimple.addWorkstep(..) methods add a new workstep as sequential workstep after all worksteps that have been added before.
The EnvelopeSimple.addWorkstepParallel(..) methods add a workstep parallel to the one workstep defined before, or to multiple worksteps that have already been defined to be parallel.

The following example defines a workflow where recipient rs1 has to finish the workstep first, but then the recipients rs2, rs3 and rs4 get their worksteps at the same time for parallel signing. All three recipients have to complete their worksteps, before recipient rs5 gets his workstep.

simpleEnvelope1.addWorkstep(rs1);
simpleEnvelope1.addWorkstep(rs2);
simpleEnvelope1.addWorkstepParallel(rs3);
simpleEnvelope1.addWorkstepParallel(rs4);
simpleEnvelope1.addWorkstep(rs5);

Advanced Use Case

Defining document specific workstep parameters

Based on a use case focused approach, the SignAnyWhereServer provides the use case to send an envelope with an envelope that has a primary workstep configuration. But document specific workstep configuration is created on server side based on a basic configuration, and the given document. So, use case is composed of two SOAP API calls:

WorkstepConfigurationSimple conf = WorkstepConfiguration.createAdHocSimple();
conf.getAdvanced().setWorkstepProcessor(new WorkstepProcessor() {

    @Override
    public void process(PreprocessedWorkstepAdapter wsConfig) {
            //your code here
    }
}

For example, you could remove signature fields from one signer’s workstep configuration:

conf.getAdvanced().setWorkstepProcessor(new WorkstepProcessor() {
    @Override
    public void process(PreprocessedWorkstepAdapter wsConfig) {

        /*
         * set signer1 to required (in the task list and in the detail
         * for the signature
         */

        SignatureFieldAdapter sig1 = wsConfig.findSigFieldByFieldDescription("signer1");
        // IMPORTANT: when using sig strings, the ID is set dynamically! so we identify the field by fd instead of its ID
        String sig1Id = sig1.getId();
        sig1.setRequired(true);

        TaskAdapter task1 = wsConfig.findTaskById(sig1Id);
        task1.setRequired(true);

        // remove signer2 from this workstep because it's for the other signer
        SignatureFieldAdapter sig2 = wsConfig.findSigFieldByFieldDescription("signer2");
        String sig2Id = sig2.getId();
        sig2.remove();

        TaskAdapter task2 = wsConfig.findTaskById(sig2Id);
        task2.remove();
    }
});

Accessing XML Elements

When the library doesn’t support a configuration feature yet, users of the AdvancedApi also have the ability to access the XML configuration directly.
Our XML based approach uses the org.w3c.dom.Document structures and so the JDK features for XML manipulation. For better accessibility of the XML, and to keep similarities in source code between Java and .NET, we provide the NetXmlUtils class with some methods that provide a .NET like behavior for XML manipulation.

For example, assuming that you cannot yet access the beforeExpirationReminderDayAmount parameter of an envelope using the API:

Document envDoc = simpleEnvelope1.getAdvanced().getXmlDocument();
try {
    Node n = NetXmlUtils.selectSingleNode(envDoc.getDocumentElement(),
            "/envelope/beforeExpirationReminderDayAmount");
    n.setTextContent("2");
    /*
     * but consider - the worksteps are not yet added to the envelope XML at this time, they
     * can be accessed using the workstep entity instances...
     */
} catch (XPathExpressionException e) {
    e.printStackTrace();
}