Java service to navigate Document (IData with complex structure)

Hi,

I have written a java service in wM 8.2 to modify the Document (with complex structure) at run time.

e.g. Say input to the service is “inputDoc” with complex structure

inputDoc (Document - IData Object)
-----strField1 (String)
-----strField2 (String)
-----internalDoc1 (Document - IData Object)
----------internalDoc1StrField1 (String)
----------internalDoc1StrField2 (String)
-----internalDoc2 (Document - IData Object)
----------doubleInternalDoc1 (Document - IData Object)
---------------doubleInternalDoc1StrField1 (String)
---------------doubleInternalDoc1StrField2 (String)

I would like to convert each leaf node i.e. strField1, strField2, internalDoc1StrField1… to a Document “info” and add three fields in it “key”, “value” and “type”

Here is the code I am using:

--------------------- Code Starts --------------------
[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]

package

[/color][/size][/COLOR][/SIZE][/b]

DevTeam.Java;

[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]

import

[/color][/size][/COLOR][/SIZE][/b]

com.wm.data.*;

[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]

import

[/color][/size][/COLOR][/SIZE][/b]

com.wm.util.Values;

[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]

import

[/color][/size][/COLOR][/SIZE][/b]

com.wm.app.b2b.server.Service;

[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]

import

[/color][/size][/COLOR][/SIZE][/b]

com.wm.app.b2b.server.ServiceException;

[B][SIZE=2][COLOR=#7f0055][SIZE=2][COLOR=#7f0055]

public

[/color][/size][/COLOR][/SIZE][/b]

finalclass documentToModifiedDoc_SVC{/** * The primary method for the Java service** @param pipeline* The IData pipeline* @throws ServiceException*/
publicstaticfinalvoid documentToModifiedDoc(IData pipeline) throws ServiceException {IDataCursor pipelineCursor = pipeline.getCursor();IData idataObj = IDataUtil.getIData(pipelineCursor, “inputDoc”);Values obj = getDocumentKeys(idataObj, pipelineCursor);IData resultIData = obj.getIData();IDataUtil.put(pipelineCursor, “Keys”, obj);IDataUtil.put(pipelineCursor, “idataObj”, resultIData);}// — <> —
publicstatic IData outputIData;publicstatic IDataCursor outCursor;publicstatic Values getDocumentKeys(IData _idata, IDataCursor pipelineCursor){outputIData = IDataFactory.create();IDataCursor _idataCursor = _idata.getCursor();outCursor = outputIData.getCursor();_idataCursor.first();//Values internalKeys;

[SIZE=2]

Values keysObj =

[/size]

new Values();IData info = IDataFactory.create();// IDataCursor infoCursor = info.getCursor();
do{// info = IDataFactory.create();

[SIZE=2]

IDataCursor infoCursor = info.getCursor();

[/size]

if (_idataCursor.getValue() instanceof IData){

[SIZE=2]

keysObj.put(_idataCursor.getKey() , getDocumentKeys((IData)_idataCursor.getValue(), pipelineCursor).getIData());

[/size]

// outCursor.insertAfter(_idataCursor.getKey(), newValues);

[SIZE=2]

}

[/size]

else{infoCursor.insertAfter(“key”, _idataCursor.getKey());infoCursor.insertAfter(“value”, _idataCursor.getValue());infoCursor.insertAfter(“type”, “String”);keysObj.putNode(“info”, info);outCursor.insertAfter(“info”, (IData)info);infoCursor.destroy();//info = null;

[SIZE=2]

}}

[/size]

while (_idataCursor.next());IDataUtil.put(pipelineCursor, “valueObject”, keysObj);//pipelineCursor.insertAfter(“outputIData”, outputIData);

[SIZE=2]

IDataUtil.put(pipelineCursor,

[/size]

“outputIData”, outputIData);return keysObj;}// — <> —

}

------------------------ End -------------------------

The output is coming, but not in the way I want, can anyone please suggest me where I am going wrong. The output I am looking for is:
outputDoc (Document - IData Object)
-----info
----------key (String)
----------value (String)
----------type (String)
-----info
----------key (String)
----------value (String)
----------type (String)
-----internalDoc1 (Document - IData Object)
----------info
---------------key (String)
---------------value (String)
---------------type (String)
----------info
---------------key (String)
---------------value (String)
---------------type (String)
-----internalDoc2 (Document - IData Object)
----------doubleInternalDoc1 (Document - IData Object)
---------------info
--------------------key (String)
--------------------value (String)
--------------------type (String)
---------------info
--------------------key (String)
--------------------value (String)
--------------------type (String)

Thanks in advance!

and what is the output you are getting?

Only one info obj is created and under that twice the key, value, type are coming

Hi,

I have written a java service in wM 8.2 to modify the Document (with complex structure) at run time.

e.g. Say input to the service is “inputDoc” with complex structure

inputDoc (Document - IData Object)
-----strField1 (String)
-----strField2 (String)
-----internalDoc1 (Document - IData Object)
----------internalDoc1StrField1 (String)
----------internalDoc1StrField2 (String)
-----internalDoc2 (Document - IData Object)
----------doubleInternalDoc1 (Document - IData Object)
---------------doubleInternalDoc1StrField1 (String)
---------------doubleInternalDoc1StrField2 (String)

I would like to convert each leaf node i.e. strField1, strField2, internalDoc1StrField1… to a Document “info” and add three fields in it “key”, “value” and “type”

Here is the code I am using:

--------------------- Code Starts --------------------
package
DevTeam.Java;
import
com.wm.data.;
import
com.wm.util.Values;
import
com.wm.app.b2b.server.Service;
import
com.wm.app.b2b.server.ServiceException;
public
finalclass documentToModifiedDoc_SVC{/** * The primary method for the Java service** @param pipeline
The IData pipeline* @throws ServiceException*/

public static final void documentToModifiedDoc(IData pipeline) throws ServiceException
{
    IDataCursor pipelineCursor = pipeline.getCursor();
    IData idataObj = IDataUtil.getIData(pipelineCursor, "inputDoc");
    Values obj = getDocumentKeys(idataObj, pipelineCursor);
    IData resultIData = obj.getIData();
    IDataUtil.put(pipelineCursor, "Keys", obj);
    IDataUtil.put(pipelineCursor, "idataObj", resultIData);
    
}
// --- <<IS-BEGIN-SHARED-SOURCE-AREA>>---
public static IData outputIData;
public static IDataCursor outCursor;
public static Values getDocumentKeys(IData _idata, IDataCursor pipelineCursor){
    outputIData = IDataFactory.create();
    IDataCursor _idataCursor = _idata.getCursor();
    outCursor = outputIData.getCursor();
    _idataCursor.first();
    //Values internalKeys;
    
    Values keysObj =
    new Values();
    IData info = IDataFactory.create();
    // IDataCursor infoCursor = info.getCursor();
    
    do{
        // info = IDataFactory.create();
        
        IDataCursor infoCursor = info.getCursor();
        
        if (_idataCursor.getValue() instanceof IData){
            
            keysObj.put(_idataCursor.getKey() , getDocumentKeys((IData)_idataCursor.getValue(), pipelineCursor).getIData());
            
            // outCursor.insertAfter(_idataCursor.getKey(), newValues);
        }
        else{
            infoCursor.insertAfter("key", _idataCursor.getKey());
            infoCursor.insertAfter("value", _idataCursor.getValue());
            infoCursor.insertAfter("type", "String");
            keysObj.putNode("info", info);
            outCursor.insertAfter("info", (IData)info);
            infoCursor.destroy();
            //info = null;
        }
    }
    
    while (_idataCursor.next());
    IDataUtil.put(pipelineCursor, "valueObject", keysObj);
    //pipelineCursor.insertAfter("outputIData", outputIData);
    
    IDataUtil.put(pipelineCursor,
    "outputIData", outputIData);
    return keysObj;
    
}
// --- <<IS-END-SHARED-SOURCE-AREA>>---
}

------------------------ End -------------------------

The output is coming, but not in the way I want, can anyone please suggest me where I am going wrong. The output I am looking for is:
outputDoc (Document - IData Object)
-----info
----------key (String)
----------value (String)
----------type (String)
----------key (String)
----------value (String)
----------type (String)
-----internalDoc1 (Document - IData Object)
----------info
---------------key (String)
---------------value (String)
---------------type (String)
---------------key (String)
---------------value (String)
---------------type (String)
-----internalDoc2 (Document - IData Object)
----------doubleInternalDoc1 (Document - IData Object)
---------------info
--------------------key (String)
--------------------value (String)
--------------------type (String)
--------------------key (String)
--------------------value (String)
--------------------type (String)

It’s coming like this!

I m not able to see complete thread, as I am replying thro my smart ph, will reply in detail.
Sorry about that!

Did you try this:

  • Define a document type conforming to the structure and field names of the source document
  • Define another document type conforming to the structure and field names of the target
  • Use FLOW service steps to map

Hi Reamon, this java service I want to use as a generic service for any document structure.
At run time, my code is reading the document structure and then modifying the fields if the field is not an IData object.

Hemanth,
yesterday, by mistake I copied the contents from the first thread and pasted in the response I was sending you.
Here is the output the code generates
-----info
----------key (String)
----------value (String)
----------type (String)
----------key (String)
----------value (String)
----------type (String)
-----internalDoc1 (Document - IData Object)
----------info
---------------key (String)
---------------value (String)
---------------type (String)
---------------key (String)
---------------value (String)
---------------type (String)
-----internalDoc2 (Document - IData Object)
----------doubleInternalDoc1 (Document - IData Object)
---------------info
--------------------key (String)
--------------------value (String)
--------------------type (String)
--------------------key (String)
--------------------value (String)
--------------------type (String)

In this output, if you see it is not adding IData object “info” for all three fields which I am adding to the output document.
Hope this answers your question on the thread…

Thanks Reamon, for formatting the thread contents, it’s much readable form now.
Just one thing was missing, my desired output is missing :).

I am looking for the output to be:

outputDoc (Document - IData Object)
-----info (Document - IData Object)
----------key (String)
----------value (String)
----------type (String)
-----info (Document - IData Object)
----------key (String)
----------value (String)
----------type (String)
-----internalDoc1 (Document - IData Object)
----------info (Document - IData Object)
---------------key (String)
---------------value (String)
---------------type (String)
----------info (Document - IData Object)
---------------key (String)
---------------value (String)
---------------type (String)
-----internalDoc2 (Document - IData Object)
----------doubleInternalDoc1 (Document - IData Object)
---------------info (Document - IData Object)
--------------------key (String)
--------------------value (String)
--------------------type (String)
---------------info (Document - IData Object)
--------------------key (String)
--------------------value (String)
--------------------type (String)

if you see the output coming from the java service is missing the “info (Document - IData Object)” at one more level…hope I am giving all the details to get solution and suggestions from experts :).

You need to do IData info = IDataFactory.create(); every time you want a new “info” document. You’re only doing one.

Hello Everybody,

I am able to create the similar kind of output if not the same one which I was expecting out of Java Service.
Here is the code I would like to share with you:
Note: “In the input/output tab of the java service add input as a document “inputDoc” and in the output tab add “outputDoc”.
You can call this service in any Flow service and map any document to inputDoc and get the result in outputDoc.”

package DevTeam.Java;
import com.wm.data.*;
import com.wm.util.Values;
import com.wm.app.b2b.server.Service;
import com.wm.app.b2b.server.ServiceException;
public final class documentToModifiedDoc_SVC
{
/**

  • The primary method for the Java service
  • @param pipeline
  • The IData pipeline
  • @throws ServiceException
    */
public static final void documentToModifiedDoc(IData pipeline) throws ServiceException {
IDataCursor pipelineCursor = pipeline.getCursor();
IData idataObj = IDataUtil.getIData(pipelineCursor, "inputDoc");
Values obj = getDocumentKeys(idataObj, pipelineCursor);
IDataUtil.put(pipelineCursor, "outputDoc", obj);
}

// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---

/** 
* The shared method for the Java service
*
* @param _idata, pipelineCursor
* The IData _idata
* The IDataCursor pipelineCursor
* @returns keysObj
* The Values keysObj
* @throws 
*/
public static IData outputIData;
public static IDataCursor outCursor;

public static Values getDocumentKeys(IData _idata, IDataCursor pipelineCursor){
outputIData = IDataFactory.create();
IDataCursor _idataCursor = _idata.getCursor();
outCursor = outputIData.getCursor();
_idataCursor.first();
Values keysObj = new Values();
IData info = IDataFactory.create();
int i =0;
int length = getNumberOfLeafFields(_idata);
IData[] infoArr = new IData[length];
IDataCursor[] info1CursorArr = new IDataCursor[length];

do{
IDataCursor infoCursor = info.getCursor();

if (_idataCursor.getValue() instanceof IData){
keysObj.put(_idataCursor.getKey() , getDocumentKeys((IData)_idataCursor.getValue(), pipelineCursor).getIData());
}else{
infoArr[i] = IDataFactory.create();
info1CursorArr[i] = infoArr[i].getCursor();
info1CursorArr[i].insertAfter("key", _idataCursor.getKey());
info1CursorArr[i].insertAfter("value", _idataCursor.getValue());
info1CursorArr[i].insertAfter("type", "String");

keysObj.put("info"+i, infoArr[i]);

info1CursorArr[i].destroy();
i++;
}
}while (_idataCursor.next());
return keysObj;
}
/** 
* The shared method for the Java service
* Get the number of fields (except IData Object) from the IData object
* @param _idata
* The IData _idata
* @returns cntr
* The int cntr
* @throws 
*/

public static int getNumberOfLeafFields(IData _idata){
IDataCursor _idata1Cursor = _idata.getCursor();
int cntr=0;
do{
if (_idata1Cursor.getValue() instanceof IData){
//do nothing
}else{
cntr++;
}
}while(_idata1Cursor.next());
return cntr; 
} 

// --- <<IS-END-SHARED-SOURCE-AREA>> ---

}

Reamon, please format it in the same way you did earlier, so it would be in readable form.
Thanks for your help!

You can add the formatting. Just put [ code ] [ /code ] tags around your code. Remove the spaces that I added here to avoid it being interpreted.

Thanks Reamon, I updated the post.