Convert JAVA object list to wM Document list

I have a requirement to remove duplicate items from a document list based on certain values.
Input Document:

—Doc
------SubDocArray
---------SubArray_A
---------SubArray_B
---------SubArray_C
---------SubArray_D

Output should be same but the document list should not contain duplicates.

To do so we can either traverse the whole list and compare each element, but it is a time consuming process.
I have passed the document list to a java service in which the contents of the list are mapped to an array of local class with all the 4 fields, and it removes the duplicates using HashSet.

But i am not able to convert the array back to document list and also it can’t be returned as output as is.

Please suggest if there is a way to convert the JAVA array to Document List
Best Regards…
Abhishek Jain

Can you post your sample Java code to understand the issue?

Hi Abhishek,

For duplicates removal, I suggest to create a webMethods Java Service and use the Java Set collection type (http://docs.oracle.com/javase/7/docs/api/java/util/Set.html).

This type eliminates duplicates for you by keeping the original order of the items included in it. You do not have to re-engineer the duplicate check yourself: if you iterate through your list and add the elements one by one to the Set Collection in case this was already included to the collection it’ll not be added again.

Regarding conversion of the array back to Document List, as Dingu also suggested, can you please share some details on your approach for this? Sample code will also help shed some light on this.

Thanks,
Ana

Hi Ana,

I have also applied the same logic(Implementing the hash set) for removing the duplicates.
The issue lies with converting the DocumentList to HashSet/ArrayList and then getting back the DocumentList from the JAVA collection type.
Though i have managed to do so as the service is running fine, but i am sure there is some more efficient way of doing so.

@Dingu Here is my JAVA code:

Input:

-input
—input/certInfo
-----input/certInfo[0]/certId
-----input/certInfo[0]/partnerId
-----input/certInfo[0]/ownerId
-----input/certInfo[0]/usage

Code:
IDataCursor idc = pipeline.getCursor();
try{
IDataCursor inCurs = IDataUtil.getIData(idc,“input”).getCursor();
IData[] certInfoList = IDataUtil.getIDataArray(inCurs,“certInfo”);
Set newSet = new HashSet();

	for(IData obj : certInfoList){
		String certId, partnerId, ownerId, usage;
		certId = IDataUtil.getString(obj.getCursor(),"certId");
		partnerId = IDataUtil.getString(obj.getCursor(),"partnerId");
		ownerId = IDataUtil.getString(obj.getCursor(),"ownerId");
		usage = IDataUtil.getString(obj.getCursor(),"usage");	
		newSet.add(new CertInfo(certId, partnerId, ownerId, usage));
	}

	ArrayList<CertInfo> outputArr = new ArrayList<CertInfo>(newSet);
	IData[] idArr = new IData[outputArr.size()];
	int i =0;

	for(CertInfo ciObj : outputArr){
		IData tempID = IDataFactory.create();
		IDataCursor tempIDC = tempID.getCursor();
		IDataUtil.put(tempIDC, "certId", ciObj.getCertId());
		IDataUtil.put(tempIDC, "partnerId", ciObj.getPartnerId());
		IDataUtil.put(tempIDC, "ownerId", ciObj.getOwnerId());
		IDataUtil.put(tempIDC, "usage", ciObj.getUsage());
		tempIDC.destroy();
		//IDataUtil.append(idArr,tempID);
		idArr[i] = tempID;
		i++;
	}

	//IDataUtil.put(idc,"String1",newSet.toString());
	IDataUtil.put(idc,"CertInfo",idArr);
	inCurs.destroy();
}catch(Exception e){
	IDataUtil.put(idc,"String1",e.toString());
}
finally{
	idc.destroy();	
}

Shared Code:

static class CertInfo implements Serializable{
private String certId, partnerId, ownerId, usage;

    // Constructors, Getter(s)/Setter(s), Equals, Hashcode methods

}

Hi Abhishek… Are u getting the required output using this code?

Yes, output is the same DocumentList as input.

Hi Abhishek,

Here are my comments after a quick review:

  • From your code I see that you have a tightly coupled logic between extracting the values of the attributes (“certId”, “partnerId”, “ownerId”, “usage”) and the order of these in the input/certInfo element.
    Since this is a Java service, if someone is changing the order of the attributes of certInfo outside of the service, it will not be easy to identify that this impacts the logic inside the Java service as well.
  • Regarding how you set the attributes of CertInto, see step “for(IData obj : certInfoList)”. You could instantiate the object first (using the default constructor) and use Setters to assign the values for each attribute. This means you will probably have to update the shared code for your class to include the Setters for each attribute as well.
  • For "for(CertInfo ciObj : outputArr){ " - you could declare “tempIDC” before the for statement, since inside you are re-assigning a value on each iteration and you are destroying it at the end of the iteration.

Apart from these it looks good.

I hope this helps,
Ana

Hi Ana,

Thanks for the feedback.

Though for the first point you mentioned, it does not matter what is the order of attributes in the CertInfo Document, as i am extracting the the values from the IDataCursor using keys.

Hi Abhishek,

Yupp, I missed that one out! :slight_smile:

Thanks,
Ana