Sorting a Record List

I’m currently using the IS 4.6. I have a record list in my flow service that I need to sort so that the output will be in the correct order. I will have records in the list that have the same key value(ShipUnit). I’m not a JAVA developer but I am very good with the building of flow services. There are no built in functions for sorting in webMethods. Any suggestions?

ShipUnit ItemNumber Quantity UPC BuyersItemNumber

Regards…

Here’s a Java service that should do the trick.
Name: sortList
Inputs:

  • itemList; record list to be sorted in-place
  • keyField; field from record to use for sorting
  • sortDescending; if “true” will sort descending

Outputs:

  • sorted; “true” if sort succeeded; “false” otherwise
  • itemList is sorted in-place

Source:[highlight=java]IData sortedItemList = null;

// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
IData itemList = IDataUtil.getIDataArray( pipelineCursor, “itemList” );
String keyField = IDataUtil.getString( pipelineCursor, “keyField” );
boolean sortDescending =
(Boolean.valueOf(IDataUtil.getString( pipelineCursor,
“sortDescending” ))).booleanValue();
pipelineCursor.destroy();

if(itemList != null)
{
sortedItemList = IDataUtil.sortIDataArrayByKey(itemList, keyField, IDataUtil.COMPARE_TYPE_COLLATION, null, sortDescending);
}

// pipeline
pipelineCursor = pipeline.getCursor();
IDataUtil.put( pipelineCursor, “sorted”, sortedItemList==null ? “false” : “true”);
pipelineCursor.destroy();[/highlight]
IDataUtil is a class defined in the API. You can look at the javadoc for it in the IS API stuff.

The only tricky part is the COMPARE_TYPE_*. I couldn’t get anything other than COMPARE_TYPE_COLLATION to work. The fourth parm to sortIDataArrayByKey is documented to be “pattern - A String specifying the pattern to sort by.” but I can’t for the life of me figure out what patterns are expected. Thus, this service only does string-based sorting. Numeric sorting won’t work right.

Thanks Rob for the JAVA sort utility. It seems to work fine for what I have.

Regards,
Ray Jasko

Can anyone please explain what the compareType in the method sortIDataArrayByKey of class IDataUtil means particularly the IDataUtil.COMPARE_TYPE_EQUALS and IDataUtil.COMPARE_TYPE_COLLATION types. Also what pattern strings should be used for compareType NUMERIC and EQUALS. So far I can only get it to work on types IDataUtil.COMPARE_TYPE_COLLATION an IDataUtil.COMPARE_TYPE_TIME. Thanks.

Roy,

Here’s an explanation I received from tech support.

I received an explanation on this from our
development team:

dataArray
the IData Array to be sorted.

key
the key to sort by

compareType
supports String and Date comparation. Supported
values: IDataUtil.COMPARE_TYPE_COLLATION and
IDataUtil.COMPARE_TYPE_TIME. Not supported are
IDataUtil.COMPARE_TYPE_EQUALS and
IDataUtil.COMPARE_TYPE_NUMERIC

pattern
The pattern of the date format (used for
COMPARE_TYPE_TIME). Default pattern if pattern is
null is “MM/dd/yyyy hh:mm:ss a”. Pattern is used
to turn the dates into longs, then the longs are
turned into strings so that in a COMPARE_TYPE_TIME
sort the sort is truely by time and not by the
formatted representation of time.

reverse
True if the sort order is descending.

Hello All,
Digging into something very old…

the above code for sorting does great, but the input record list is also modified.

Could any one help… I want the record list inputted to remain unchanged.

Thanks

That’s right, the input list is sorted in place, per the comments:

  • itemList; record list to be sorted in-place

To create a new list, you’ll need to create a deep clone of your list. Depending on the version of IS you have, I believe there is a deep clone method somewhere but not sure where.

Hello,
Did try to add the Cloning, but ended with null pointer exception when running the service. The java code is getting compiled without errors. I am working on Version 4.6.

Here is the changed code

IData sortedItemList = null;
IData itemListClone = sortedItemList;

// pipeline

IDataCursor pipelineCursor = pipeline.getCursor();
IDataCursor pipelineCursor1 = pipeline.getCursor();
IData itemList = IDataUtil.getIDataArray( pipelineCursor, “itemList” );
try {

if (itemList != null)
{
for (int i=0;i<itemList.length;i++)
if (itemList[i] != null)
itemListClone[i] = IDataUtil.deepClone(itemList[i]);
}
String keyField = IDataUtil.getString( pipelineCursor, “keyField” );
boolean sortDescending = (Boolean.valueOf(IDataUtil.getString( pipelineCursor, “sortDescending” ))).booleanValue();
pipelineCursor.destroy();

if(itemList != null)
{
sortedItemList = IDataUtil.sortIDataArrayByKey(itemList,keyField,
IDataUtil.COMPARE_TYPE_COLLATION, null,sortDescending);
}

}catch (IOException e) {}

// pipeline
pipelineCursor1 = pipeline.getCursor();
IDataUtil.put( pipelineCursor1,“sortedList”,sortedItemList);
pipelineCursor1.destroy();

The problem I see is itemListClone has no “size” so

itemListClone[i] = IDataUtil.deepClone(itemList[i]);

will error out because there is no [i]'th element to store data in.

-Thomas

Is there any service available that can sort a recordList with more than KeyField specificed. It will be great if someone can guide me with this.

Thanks in advance

Has anyone seen peculiar behavior sorting record lists using a double as the key field?

In some testing today, I have seen inconsistent instances in which the array element with the max key value is sorted first in the list. The rest of the sorted array appears to be correct.

I suppose this could be an example of unsupported compare types since the only supported types appear to be String and Time.

Has anyone attempted to extend an IData to implement the java Comparator interface so that you could simply sort an IData array?

Has anyone implemented a record list sort that sorts on more than one key?

Mark

Hello,
Does any one know how I can sort a document list based on one of the elements in the document list?
Regards,

Thanks for the suggestion… I was wondering what class does isUniqueElem method belong to?

Hi there

About the sorting, if you want to sort Documents in a meaningful way, try to create a Comparator and Comparable class as a inner class in a Java service. This is a fast & stable manner to sort in Java. Takes a little coding (see the Java tutorial on how to use Comparable/Comparator).

About the cloning, the deepClone is doing not too well on performance. The easiest way to clone a document is to convert it to an XML string (thus removing the reference to the original object) & reconvert it back to Document (which results in a new Object). You don’t even need Java for that :wink:

Java is great but you should also consider other people working with you on projects. There are still lots of wm users who do not manage Java as well as others. Regarding maintainability, you should always weigh the performance of Java against the maintainability of flows.

PS. I do love to use Java for everything :wink:

Chris

sorry the includes are:
java.util.*
java.util.Vector
java.text.*

Christian,

I’ve thought about using the comparator/comparable approach in the past, but haven’t had the time to spend sorting this out (pun intended). Do you have any examples of doing this for Values/IData?

Mark

Well, that is a bit of an issue. I do have an implementation but if I place that on wMUsers I’m violating Intellectual Property regulations as everything I write is automatically owned by my employer. As this implementation is part of our products & services, it is a bit tricky to give it out.

I do however can give you a number of tips:

  1. Create a class extending Comparable to enclose the Document object.
  2. Create a class extending Comparator to match the Comparable objects.
  3. Make sure that there are no ‘equals’, so == will mean <or>.
  4. Put both classes as inner classes in the ‘shared’ section.
  5. Download sample code from developer.sun.com.

This should make it peaches & cream for you.

Good luck, Chris

In step 1, did you enclose the Document object or was it Values or IData?

Mark

Well, the Values object is more or less deprecated in IS 601, so I have used IData objects.

The Comparable is an object that holds an IData object as one of its attributes. It has a number of getter methods for retrieving the values of the fields you are sorting on.
The Comparator is the functional part. It handles the matching of 2 Comparable objects and decides whether or not object 1 preceeds object 2.

Chris

Here Outbound process i am using document in that whenever i am running this its is giving this exception

$errorDump com.wm.lang.flow.FlowException:[ISS.0085.9159] Invalid input. ‘document’ is a required parameter of type IData
$error [ISS.0085.9159] Invalid input. ‘document’ is a required parameter of type IData
$localizedError [ISS.0085.9159] Invalid input. ‘document’ is a required parameter of type IData
$errorType com.wm.lang.flow.FlowException
$service wm.PartnerMgr.flows.MD1070.SAP_WM_LYNX_MD1070:Z_ERP2_MM_EDIDC_SOX_COMPLIANCE
$user skaturi
$time 2005-04-21 13:42:23 EDT
$pipeline Severity 1
PU009_LYNX_CMDC_Publish_v1.ExceptionHandler.docs:PublishError SourceSystem CMDC
InterfacePoint GDS - pubSOxReportRequest
ReferenceID PU009_TBICanonicals_v1.docs.UDMDocuments:RequestDocument
Severity 1
Timestamp 2005/04/21 13:42:21.719
InitiatingDocument Name GDS SOx Report Data Request
Data

Errors Type com.wm.app.b2b.server.ServiceException
SystemCode
Message [ISS.0085.9159] Invalid input. ‘document’ is a required parameter of type IData

SourceSystem Cornerstone
strLastError [ISS.0085.9159] Invalid input. ‘document’ is a required parameter of type IData
tranService wm.PartnerMgr.gateway.transport.B2ButboundProcess
transportParams serverAlias (local)
valueScope SESSION
servicePath PU009_LYNX_GDS_ERP2Subscribe_v1.IDOCReconciliation
service pubIDOCReconRequest

InitiatingDocumentName GDS SOx Report Data Request

$details
$errorMsgId
$callStack $service wm.PartnerMgr.gateway.transport.B2ButboundProcess
$currentPath

$service wm.PartnerMgr.flows.MD1070.SAP_WM_LYNX_MD1070:Z_ERP2_MM_EDIDC_SOX_COMPLIANCE
$currentPath /3

$error [ISS.0085.9159] Invalid input. ‘document’ is a required parameter of type IData
$errorType com.wm.lang.flow.FlowException