Blog Post

Using the Muhimbi PDF Converter Services from Java Using Apache Axis2

Clavin Fernandes
Illustration: Using the Muhimbi PDF Converter Services from Java Using Apache Axis2

Many of our customers use the Muhimbi PDF Converter Services from Java based environments to Convert, Watermark, Merge and Secure common document types including MS-Office, AutoCAD, HTML and Images. This is made particularly easy because we ship Java based sample code with the product (in addition to C# samples).

However, to keep things as simple as possible, and the number of external dependencies to a minimum, so far our sample code has been using wsimport to generate Java based web service proxy classes. Unfortunately wsimport does not generate very friendly syntax and, even worse, does not support Web Services that expose derived classes (A feature used by some of our more advanced facilities).

All is not lost as Apache’s Axis2 Web Services framework solves both problems. The generated proxy classes are much easier to use and derived classes can be populated and sent to the server without problems.

Below you will find an example about how to setup Apache Axis, generate proxy classes and use those classes to convert a document to PDF. This is just a simple sample, for full details see the Developer Guide. It is assumed that you are familiar with Java. Our samples are generated using Microsoft Windows, please note that the command line syntax on other platforms may be slightly different.

The full version of the sample code discussed in this post, including pre generated proxies, is installed alongside each copy of the Muhimbi Converter Server Platform, starting with version 7.0. It is also available here and includes Windows batch files for generating the proxies, compiling and executing the code.

The example described below assumes the following:

  1. JDK 1.5 (or newer) has been installed and configured.

  2. JAVA\_HOME is set and javac is on the path.

  3. The Muhimbi Conversion Service and all prerequisites have been installed in line with the Administration Guide.

  4. The Muhimbi Conversion Service is running in the default anonymous mode. This is not an absolute requirement, but it makes initial experimentation much easier.

Installing Axis2

The installation process for Axis 2 is relatively simple. The steps are as follows:

  1. Download the Axis2 binary distribution

  2. Unpack and place axis2-<version> in a location of your choice. (This will be your AXIS2\_HOME).

  3. Have a look at installation-std-bin.txt and set environment variables depending on your platform.

  4. Add %AXIS2\_HOME%\\bin to your Path to make sure the executables can be found.

  5. On non-Windows Machines execute chmod 744 $AXIS2\_HOME/bin/\*.sh

Generating Proxies

With all the prerequisites in place you can generate proxy classes for the web service by executing the following command:

wsdl2java.bat -uri https://localhost:41734/Muhimbi.DocumentConverter.WebService/?wsdl -p com.muhimbi.ws

Feel free to change the package name to something more suitable to your organisation. The example below assumes com.muhimbi.ws is used.

If the Muhimbi Conversion Service is not located on the same system as where wsdl2java is executed then change localhost to the name of the server running the Conversion Service. You will also need to change the host name in the Conversion Service’s config file. A convenient shortcut to the Installation folder is located in the Muhimbi Start Menu Group. Open Muhimbi.DocumentConverter.Service.exe.config, search for baseAddress and change the host name. Restart the Muhimbi Document Converter Service to activate the change.

Sample Code

The sample code is as follows. Please note that exception handling has been omitted for the sake of clarity. This is a minimal example, for full details see the Developer Guide. (Download Source Code)

package com.muhimbi.app;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;
import java.util.Arrays;
import java.util.List;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;

import com.muhimbi.ws.DocumentConverterServiceStub;
import com.muhimbi.ws.DocumentConverterServiceStub.Configuration;
import com.muhimbi.ws.DocumentConverterServiceStub.ConversionFidelities;
import com.muhimbi.ws.DocumentConverterServiceStub.ConversionFidelities_type0;
import com.muhimbi.ws.DocumentConverterServiceStub.ConversionQuality;
import com.muhimbi.ws.DocumentConverterServiceStub.ConversionRange;
import com.muhimbi.ws.DocumentConverterServiceStub.ConversionSettings;
import com.muhimbi.ws.DocumentConverterServiceStub.Convert;
import com.muhimbi.ws.DocumentConverterServiceStub.ConvertResponse;
import com.muhimbi.ws.DocumentConverterServiceStub.ConverterConfiguration;
import com.muhimbi.ws.DocumentConverterServiceStub.ConverterSpecificSettings_WordProcessing;
import com.muhimbi.ws.DocumentConverterServiceStub.GetConfiguration;
import com.muhimbi.ws.DocumentConverterServiceStub.OpenOptions;
import com.muhimbi.ws.DocumentConverterServiceStub.OutputFormat;
import com.muhimbi.ws.DocumentConverterServiceStub.RevisionsAndCommentsDisplayMode;
import com.muhimbi.ws.DocumentConverterServiceStub.RevisionsAndCommentsMarkupMode;
import com.muhimbi.ws.DocumentConverterService_Convert_WebServiceFaultExceptionFault_FaultMessage;
import com.muhimbi.ws.DocumentConverterService_GetConfiguration_WebServiceFaultExceptionFault_FaultMessage;

public class WsClient {

  private final static String CONVERTERSERVICE_WSDL_LOCATION =
    "https://localhost:41734/Muhimbi.DocumentConverter.WebService/?wsdl";

  public static void main(String[] args)
  throws DocumentConverterService_Convert_WebServiceFaultExceptionFault_FaultMessage, IOException,
  DocumentConverterService_GetConfiguration_WebServiceFaultExceptionFault_FaultMessage {
    if (args.length != 1) {
      System.out.println("Please specify a single file name on the command line.");
    } else {
      String fileNameFull = args[0];
      String fileExt = fileNameFull.lastIndexOf(".") == -1 ? "" :
        fileNameFull.substring(fileNameFull.lastIndexOf(".") + 1);
      String fileName = fileNameFull.replace("." + fileExt, "");

      DocumentConverterServiceStub stub = new DocumentConverterServiceStub(CONVERTERSERVICE_WSDL_LOCATION);

      // ** Is the file extension supported by the Converter?
      if (!"".equals(fileExt) && fileExtensionSupported(fileExt, stub)) {
        // ** Specify the minimum conversion settings
        ConversionSettings settings = new ConversionSettings();
        settings.setFormat(OutputFormat.PDF);
        settings.setQuality(ConversionQuality.OptimizeForPrint);
        settings.setRange(ConversionRange.VisibleDocuments);

        // ** Only send WordProcessing specific settings if the file is in MS-Word format.
        // ** This is just an example to demonstrate the use of derived classes in Axis2.
        if ("doc".equalsIgnoreCase(fileExt) || "docx".equalsIgnoreCase(fileExt)) {
          ConverterSpecificSettings_WordProcessing csc = new ConverterSpecificSettings_WordProcessing();
          csc.setRevisionsAndCommentsDisplayMode(RevisionsAndCommentsDisplayMode.OriginalShowingMarkup);
          csc.setRevisionsAndCommentsMarkupMode(RevisionsAndCommentsMarkupMode.Balloon);
          csc.setProcessDocumentTemplate(false);
          settings.setConverterSpecificSettings(csc);
        }

        ConversionFidelities fi = new ConversionFidelities();
        fi.setConversionFidelities_type0(new ConversionFidelities_type0[] {
          ConversionFidelities_type0.Full
        });
        settings.setFidelity(fi);

        // ** Set the minimum open options
        OpenOptions oo = new OpenOptions();
        oo.setFileExtension(fileExt);

        Convert con = new Convert();
        // ** Read the contents of the file to convert into a byte array.
        con.setSourceFile(new DataHandler(new FileDataSource(fileNameFull)));
        con.setConversionSettings(settings);
        con.setOpenOptions(oo);

        // ** Carry out the conversion and save the results.
        ConvertResponse res = stub.convert(con);
        saveResult(res.getConvertResult().getInputStream(), fileName + ".pdf");

      } else {
        System.out.println("File extension not supported or not specified.");
      }
    }
  }

  private static void saveResult(InputStream in , String file) throws IOException {
    FileOutputStream out = new FileOutputStream(file);

    int i = 0;
    while ((i = in.read()) != -1) {
      out.write(i);
    }
    out.flush();
    out.close();
    in.close();
  }

  private static boolean fileExtensionSupported(String fileExt, DocumentConverterServiceStub stub) throws
  RemoteException, DocumentConverterService_GetConfiguration_WebServiceFaultExceptionFault_FaultMessage {

    Configuration configuration = stub.getConfiguration(new GetConfiguration()).getGetConfigurationResult();
    ConverterConfiguration[] converters = configuration.getConverters().getConverterConfiguration();

    for (ConverterConfiguration cc: converters) {
      List < String > supportedExtension = Arrays.asList(cc.getSupportedFileExtensions().getString());
      if (supportedExtension.contains(fileExt)) {
        return true;
      }
    }
    return false;
  }
}

Compiling Code

How to compile your code very much depends on your environment, solution and build system. To build the sample code in this blog post use the following:

rmdir /S /Q .\\bin
md bin
javac -d ./bin -cp "%AXIS2\_HOME%/lib/\*"  -verbose ./src/com/muhimbi/ws/\*.java
javac -d ./bin -cp "./bin;%AXIS2\_HOME%/lib/\*" -verbose ./src/com/muhimbi/app/\*.java

Please note that on non-Windows platforms the classpath (-cp) separator is : rather than ;.

Running the Code

To execute the code and carry out the PDF conversion of a file named test.docx issue the following command.

java -classpath "./bin;%AXIS2\_HOME%/lib/\*" com.muhimbi.app.WsClient test.docx

Please note that on non-Windows platforms the classpath (-cp) separator is : rather than ;.

If you have any questions then leave a comment below or contact us at [email protected].

Author
Clavin Fernandes Developer Relations and Support Services

Clavin is a Microsoft Business Applications MVP who supports 1,000+ high-level enterprise customers with challenges related to PDF conversion in combination with SharePoint on-premises Office 365, Azure, Nintex, K2, and Power Platform mostly no-code solutions.

Explore related topics

Share post
Free trial Ready to get started?
Free trial