Showing posts with label document. Show all posts
Showing posts with label document. Show all posts

Thursday 15 August 2013

Handling JSON in the ESB

Introduction

In version 9.x of webMethods, JSON support is out of the box, however for the older versions, you need to write your own handler.
This article will provide sample code on how to use GSON (Google's JSON parser) to handle JSON strings and arrays in the ESB.
We are assuming your IData objects are of type key (String) and value (Object)

IS Java Services

JSONToDocument

public static final void JSONToDocument(IData pipeline) throws ServiceException {
// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
String jsonString = IDataUtil.getString(pipelineCursor, "jsonString");
pipelineCursor.destroy();

Gson gson = new Gson();
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> jsonMapList = gson.fromJson(jsonString, type);
IData document = convertToIData(jsonMapList);
// pipeline
IDataCursor pipelineCursor_1 = pipeline.getCursor();
IDataUtil.put(pipelineCursor_1, "document", document);
pipelineCursor_1.destroy(); }

JSONToDocumentList

public static final void JSONToDocumentList(IData pipeline) throws ServiceException {
// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
String jsonString = IDataUtil.getString(pipelineCursor, "jsonString");
pipelineCursor.destroy();

Gson gson = new Gson();
Type type = new TypeToken<List<Map<String, Object>>>() {}.getType();
List<Map<String, Object>> jsonMapList = gson.fromJson(jsonString, type);
List<IData> docList = new ArrayList<IData>()
for(Map<String, Object> map : jsonMapList) {
docList.add(convertToIData(map));
}
IData[] documentList = new IData[docList.size()];
docList.toArray(documentList);
// pipeline
IDataCursor pipelineCursor_1 = pipeline.getCursor();
IDataUtil.put(pipelineCursor_1, "documentList", documentList);
pipelineCursor_1.destroy();
}

DocumentToJSON

public static final void documentToJSON(IData pipeline) throws ServiceException {
// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
IData document = IDataUtil.getIData(pipelineCursor, "document");
String callback = IDataUtil.getString(pipelineCursor, "callback");
if(document == null) {
return;
}
Map result = convertToMap(document, new HashMap());
Gson gson = new Gson();
String jsonString = gson.toJson(result);
if(callback != null && !callback.isEmpty()) {
jsonString = callback + "(" + jsonString + ")";
}
IDataUtil.put(pipelineCursor, "jsonString", jsonString);
pipelineCursor.destroy();
}

DocumentListToJSON

public static final void documentListToJSON(IData pipeline)
throws ServiceException {
// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
IData[] documentList = IDataUtil.getIDataArray(pipelineCursor, "documentList");
String callback = IDataUtil.getString(pipelineCursor, "callback");
if(documentList == null) {
return;
}
List> result = new ArrayList>();
for(IData data : documentList) {
result.add(convertToMap(data, new HashMap()));
}
Gson gson = new Gson();
String jsonString = gson.toJson(result);
if(callback != null && !callback.isEmpty()) {
jsonString = callback + "(" + jsonString + ")";
}
IDataUtil.put(pipelineCursor, "jsonString", jsonString);
pipelineCursor.destroy();
}

Shared Code

public static Map convertToMap(IData data, Map map) {
IDataCursor dataCursor = data.getCursor();
while(dataCursor.next()) {
Object key = dataCursor.getKey();
Object val = dataCursor.getValue();
if (val instanceof IData[]) {
IData[] ida = (IData[]) val;
List> valueList = new ArrayList>();
for (int l = 0; l < ida.length; l++) {
valueList.add(convertToMap(ida[l], new HashMap()));
}
map.put(String.valueOf(key),valueList);
} else if (val instanceof IData) {
map.put(String.valueOf(key),convertToMap((IData)val, new HashMap()));
} else {
map.put(String.valueOf(key), val);
}
}
dataCursor.destroy();
return map;
}
public static IData convertToIData(Map map) {
IData doc = IDataFactory.create();
IDataCursor docCursor = doc.getCursor();
for(Entry entry : map.entrySet()) {
if(entry.getValue() instanceof List) {
List> list = (ArrayList>) entry.getValue();
List docList = new ArrayList();
for(Map m : list) {
docList.add(convertToIData(m));
}
IData[] docArray = new IData[docList.size()];
IDataUtil.put(docCursor, entry.getKey(), docList.toArray(docArray));
} else {
IDataUtil.put(docCursor, entry.getKey(), entry.getValue());
}
}
docCursor.destroy();
return doc;
}

Monday 7 May 2012

Merging IS document to LiveCycle PDF

Introduction

The following post outlines what is required to merge data from an IS document to an Adobe LiveCycle Static PDF form.

Prerequisites

  • Adobe Livecycle Static PDF Form
  • iText jars in package
  • Names used in Static form are the same as in IS Document, otherwise data won't be merged

IS Code

Inputs/Outputs:
  • Document - IS document containing data
  • pdfFormTemplate - full file path of the Adobe Livecycle Static PDF form
  • pdfBytes - byte[] containing merged data




import com.wm.data.*;
import com.wm.util.Values;
import com.wm.app.b2b.server.Service;
import com.wm.app.b2b.server.ServiceException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Set;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.wm.data.IData;
import com.wm.data.IDataCursor;
import com.wm.data.IDataUtil;
import com.wm.util.coder.IDataCodable;

public final class documentToPdfBytes_SVC

{

 /**
  * The primary method for the Java service
  *
  * @param pipeline
  * The IData pipeline
  * @throws ServiceException
  */
 public static final void documentToPdfBytes(IData pipeline)
   throws ServiceException {
 
  // pipeline
  IDataCursor pipelineCursor = pipeline.getCursor();
  IData document = IDataUtil.getIData(pipelineCursor, "document");
  if (document == null) {
   throw new ServiceException("No document provided");
  }
  HashMap<String,String> fieldMap = new HashMap<String, String>();
  String pdfFormTemplate = IDataUtil.getString( pipelineCursor, "pdfFormTemplate" );
  byte[] pdfBytes = null;
  try {
   populateHashMap(document, fieldMap);
   pdfBytes = createPdfData(pdfFormTemplate, fieldMap);
  } catch(Exception e) {
   throw new ServiceException(e);
  }
  // pipeline
  IDataUtil.put(pipelineCursor, "pdfBytes", pdfBytes);
  pipelineCursor.destroy();
   
 }
 
 // --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---
 
 /**
  * Fill out a form the "traditional way".
  * @param pdfTemplate the original PDF
  * @param outputFile the final signed output PDF file
  * @param fieldMap {@link HashMap} of IData key/value pairs in the input document
  * @throws Exception
  */
 private static byte[] createPdfData(String pdfTemplate, HashMap<String, String> fieldMap) throws Exception {
  RandomAccessFileOrArray raf = new RandomAccessFileOrArray(pdfTemplate);
  PdfReader reader = new PdfReader(raf,null);
  
  File tmpFile = File.createTempFile("cpv", ".pdf");
  tmpFile.deleteOnExit();
  PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tmpFile));
 
  AcroFields form = stamper.getAcroFields();
  form.removeXfa();
  Set<String> fields = form.getFields().keySet();
  if(fields.size() == 0) {
   throw new ServiceException("No AcroFields in this pdf template "+ pdfTemplate);
  }
  for(String s : fields) {
   for(String key : fieldMap.keySet()) {
    if(s.contains(key)) {
     form.setField(s, fieldMap.get(key));
    }
   }
  }
  stamper.setFormFlattening(true);
  stamper.close();
 
  byte[] fileBytes = getBytesFromFile(tmpFile);
  return fileBytes;
 }
 
 // Returns the contents of the file in a byte array.
 private static byte[] getBytesFromFile(File file) throws IOException {
  InputStream is = new FileInputStream(file);
 
  // Get the size of the file
  long length = file.length();
 
  // You cannot create an array using a long type.
  // It needs to be an int type.
  // Before converting to an int type, check
  // to ensure that file is not larger than Integer.MAX_VALUE.
  if (length > Integer.MAX_VALUE) {
  // File is too large
  }
  // Create the byte array to hold the data
  byte[] bytes = new byte[(int)length];
 
  // Read in the bytes
  int offset = 0;
  int numRead = 0;
  while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
  offset += numRead;
  }
  // Ensure all the bytes have been read in
  if (offset < bytes.length) {
  throw new IOException("Could not completely read file "+file.getName());
  }
  // Close the input stream and return bytes
  is.close();
  return bytes;
 }
 
 /**
  * @param in {@link IData} pipeline document
  * @param fieldMap {@link HashMap} map of document fields
  * @param indent
  * @throws ServiceException
  */
 private static void populateHashMap(IData in, HashMap<String,String> fieldMap) throws ServiceException {
  IDataCursor idc = in.getCursor();
  for (int i = 0; idc.next(); i++) {
   Object key = idc.getKey();
   Object val = idc.getValue();
   if (val instanceof IData[]) {
    IData[] ida = (IData[]) val;
    for (int l = 0; l < ida.length; l++) {
     populateHashMap(ida[l], fieldMap);
    }
   } else if (val instanceof IData) {
    populateHashMap((IData)val, fieldMap);
   } else if (val instanceof IDataCodable[]) {
    IDataCodable[] ida = (IDataCodable[]) val;
    for (int l = 0; l < ida.length; l++) {
     populateHashMap(ida[l].getIData(), fieldMap);
    }
   } else {
    if(val != null) {
     fieldMap.put(key.toString(), val.toString());
    }
   }
  }
  idc.destroy();
 }
 
 private static void logMessage(Object msg) {
  IData input = IDataFactory.create();
  IDataCursor inputCursor = input.getCursor();
  IDataUtil.put(inputCursor, "message", "field: "+msg.toString());
  try {
   Service.doInvoke("pub.flow","debugLog", input);
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  inputCursor.destroy();
 }
  
 
 // --- <<IS-END-SHARED-SOURCE-AREA>> ---
}