Manipulating a webMethods String List within a Java Service

If I pass a String List into a Java service and want to treat the String List as an array (i.e. add/append an element to the end of the String List), what is the best way to do it within the Java service?

Should I call the doInvoke method in the ServerAPI and invoke pub.list:appendToStringList? If so, how do I properly pass the parameters?

On a related note, I have already built the B2B Flow to handle this operation. I will post it shortly.

A String List is already declared as a String array by the server. Check out Appendix C of the Integrator Guide. Hence, in your Java service, you could do something like this:

cursor.first(“myStringList”);
String oldArray = (String)cursor.getValue();
String newArray = new String[oldArray.length + 1];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
newArray[oldArray.length] = “newString”;
cursor.setValue(newArray);

I used your code and did some testing.

Processing a 608K inbound EDI document, the performance difference using your suggestion (above) versus my original Flow was negligable. The difference was .65 seconds over the 608K document, to be exact.

My goal is to grow the String Array without dragging down performance by creating a new String Array of length [inStringArray.length +1] with each iteration of a loop sequence. Can this be done?

Hi Dan,
What if you use another Java collection, like a Vector, to hold on to your Strings? If you want to maintain a varying size array, I believe Vectors are better than creating new arrays. You also wouldn’t have to do any copying. This may make accessing the data in B2B a little clunky since it will just be represented as an object, but if you create another java service to pull a string out of a Vector – with the B2B inputs being the vector object and a key – it may improve your performance.

Regards,
Joss

Joss, if I create the Vectors and then pass them out of the Java service as webMethods Objects, won’t I have to explicitly cast them as Vectors when I pass them back into a different Java Service?

Will the B2B Server recognize that two of the Objects in the pipeline are Vectors so I can avoid casting them?

If you want your next Java Service to call Vector methods, you’re right you would have to cast the object. Otherwise, the code won’t compile. If you grab the vector and then add a string to it, your code would look something like:

IDataCursor pipeCursor = pipeline.getCursor();
pipeCursor.first( “VectorStore” );

Vector myVect = (Vector) pipeCursor.getValue();

pipeCursor.first( “inString” );
String inputString = pipeCursor.getValue();

myVect.add( inputString );

pipeCursor.first( “VectorStore” );
pipeCursor.setValue( myVect );

You don’t have to explicitly upcast the Vector back to an Object.

Please let me know if it does the job…

~Joss

Joss, you were right. Look at these numbers:

BEFORE: Processed 608K of EDI data in 50.811 sec (717K/min)
AFTER: Processed 608K of EDI data in 29.441 sec (1.23MB/min)

Your Vector approach saved 21.37 sec – 42% less time to execute the same transaction!

Here is the code that I am now using:

[begin code for Java Service “buildVector”]
boolean isFound = false;

// pipeline
IDataHashCursor pipelineCursor = pipeline.getHashCursor();
pipelineCursor.first( “vectorECS” );
Vector vECS = (Vector) pipelineCursor.getValue();
pipelineCursor.first( “vectorCC” );
Vector vCC = (Vector) pipelineCursor.getValue();
pipelineCursor.first( “currencyCode” );
//This is the currency code of the EDI segment in this iteration over the loop of EDIValues
String currencyCode = (String) pipelineCursor.getValue();
pipelineCursor.first( “string” );
//This is the entire EDI segment in this iteration over the loop of EDIValues
String string = (String) pipelineCursor.getValue();

ListIterator vCCIterator = vCC.listIterator();

int i = 0;
loop: while ( vCCIterator.hasNext() ) {
if ( vCCIterator.next().equals(currencyCode) ) {
StringBuffer s = new StringBuffer( (vECS.get(i).toString() ) );
s.append(string);
vECS.set(i, s);
isFound = true;
break loop;
}
i++;
}

if (isFound == false) {
vECS.addElement(string);
vCC.addElement(currencyCode);
}

// pipeline
pipelineCursor.last();
pipelineCursor.insertAfter(“vectorECS”, vECS );
pipelineCursor.last();
pipelineCursor.insertAfter(“vectorCC”, vCC );
pipelineCursor.destroy();
[end code for Java Service “buildVector”]

Later, I build a String object from the Vector for EDI use. That code looks like this:

[begin code for Java service “buildStringFromVector”]
// pipeline
IDataHashCursor pipelineCursor = pipeline.getHashCursor();
pipelineCursor.first( “vectorECS” );
Vector vECS = (Vector) pipelineCursor.getValue();
pipelineCursor.destroy();

ListIterator vECSIterator = vECS.listIterator();

int j= 0;
StringBuffer sbECS = new StringBuffer ();
while ( vECSIterator.hasNext() ) {
vECSIterator.next();
sbECS.append (vECS.get(j).toString() );
j++;
}

String stringECS = sbECS.toString();

// pipeline
IDataHashCursor pipelineCursor_1 = pipeline.getHashCursor();
pipelineCursor_1.last();
pipelineCursor_1.insertAfter( “stringECS”, stringECS );
pipelineCursor_1.destroy();
[end code for Java service “buildStringFromVector”]

Thanks so much for your help.

Hi,

I have a requirement where ‘ALL’ should be in the beginning of a stringlist and the rest of the values should be fetched from database. for example: my output should look like this::

ALL
India
US
Japan

Can somebody help me here.

Regards
Jyoti

Do you have the data items already in the string list? I am asking you because the output of select adapter service is a doc list.

If you have the data already in string list I can suggest you few lines of code to meet your requirement.

I am giving you an hint make use of pub.list:appendToStringList

Or you need to check the Java API for your webMethods version to write a java service to add the item to the top of the list.

You have to make a choice now.