Comparing objects

Hi all,

I’m very fresh here in the webmethods space, but have been testing it various functions to see what it can do. I have a fairly standard case and I would like to know what is the best method to do this in Webmethods.

I have 2 cloud systems which I have connected to via API and retrieved a list of objects from each. Any objects that exist in System A, but not in system B; I want to create in System B. I have got stuck trying to compare the 2 lists with each other to first determine which do not exist in System B (before then creating them). My approach thus far as been using the Transform and Filter, however I suspect I may need to create a flow or custom node.js to do this?

Is someone able to assist with what the best approach is to take?

TIA
Rob

Hello Rob,

The best way is to use flowservice for dealing with these comparison of objects.

Regards,
Bharath

You need to describe what you mean by Object and what you mean by comparison. for instance is the comparison simply a question of checking for existence of an id/key or do you need to compare every attribute between them to detect synchronisation issues.

If dealing with a complex structure that has to be identical you would need a java service that goes through each attribute of one of the objects, checking if it exists in the other and comparing values. However, do you want to then check in the opposite direction, in case there are attributes in the other that aren’t in the former.

Find an example here, paste the static methods below into the shared area of java service and then call it

boolean isSame = compare(doc1, doc2);

It assumes that your inputs are documents i.e. IData and that you only have well behaved types in your structure i.e. IData, IData or any base java type as an array or instance.

regards,
John.

		// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---
	
	
	private static boolean compare(IData doc1, IData doc2) {
		
		boolean fail = false;
		
		if (doc2 != null) {
			
			if (doc1 != null) {
				
				IDataCursor d1 = doc1.getCursor();
				IDataCursor d2 = doc2.getCursor();
				
				d1.first();
				
				do {
					
					String key = d1.getKey();
					Object origValue = d1.getValue();

					Object compareValue = IDataUtil.get(d2, key);
						
					if (compareValue != null && compareValue.getClass().equals(origValue.getClass())) {
						fail = comparator(origValue, compareValue);
					} else {
						fail = true;
					}
		            
					// no match and no point continuing
					
					if (fail) {
						break;
					}
		                        
				} while (d1.next());
				
				d2.destroy();
				d1.destroy();
			} else {
				fail = true;
			} 
		} else {
			fail = true;
		}
		
		return !fail;
	}
		
	private static boolean comparator(Object origValue, Object compareValue) {
		
		boolean fail = false;
		
		if (origValue instanceof IData) {
        	fail = compare((IData) origValue, (IData) compareValue);
        } else if (origValue instanceof IData[]) {
        	IData[] origValueArray = (IData[]) origValue;
        	IData[] compareValueArray = (IData[]) compareValue;
        	
        	if (origValueArray.length == compareValueArray.length) {
        		for (Object oi : origValueArray) {
        			
        			// scan other array from start to beginning, break out when we find match
        			boolean gotOne = false;
        			for (Object ci: compareValueArray) {
        				if (comparator(oi, ci)) {
        					gotOne = true;
        					break;
        				}
        			}
        			
        			// no match found, break out of loop, return fail
        			if (!gotOne) {
        				fail = true;
        				break;
        			}
        		}
        	}
        } else {
        	fail = !origValue.equals(compareValue);
        }
		
		return !fail;
	}

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

Oh,
by the way you should create your “compare” java service in a packages called **Commons or **Public, so that you can use it with any project, replace the ** with your initials.

Every developer worth his salt has a commons package that they reuse everywhere.

Mine is called JcPublicTools for instance, and you can find it on gitHub

Strangely I don’t have a comparison service, so I had to roll the above and it’s not tested so give the wheels a good kicking beforehand.

regards,
John.

1 Like

Great resource. Thanks for sharing here this info John. :slight_smile:

Hi,

When comparing two documents I am just thinking about looping over the first document and then perform a XQL Query against the second document to check if the value exists there.
If it is found skip the record, if it is not found add it.

See IS Built-In-Services Reference for Chapter “pub.xml” for details on the XMLQuery service.

By doing so there is only one loop needed and not two nested loops.

Regards,
Holger