Step 4: Result

Great, now we have an AnalysisResultFuture , and we've determined that it was successful. What can we do with it?

The results of each analyzer of the job are available through the 'AnalysisResult' interface, which AnalysisResultFuture implements. Note that the analyzer result types are very different from each other. For instance, the 'Insert into table' analyzer produces a WriteDataResult , while the 'Pattern finder' produces a PatternFinderResult . Let's see how you can extract information from them:

			// demonstrate the the result
			// future implements the AnalysisResult interface, which is sufficient
			// for all the followin operations
			AnalysisResult analysisResult = resultFuture;
			List<AnalyzerResult> results = analysisResult.getResults();
			for (AnalyzerResult result : results) {

			  if (result instanceof WriteDataResult) {
			    WriteDataResult writeDataResult = (WriteDataResult)result;
			    System.out.println("Inserted " + writeDataResult.getWrittenRowCount() + " records");
			  }

			  if (result instanceof PatternFinderResult) {
			    PatternFinderResult patternFinderResult = (PatternFinderResult)result;
			    int matches = patternFinderResult.getMatchCount("Aaaaa Aaaaa")
			    int total = patternFinderResult.getTotalCount();
			    System.out.println("There where " + matches + " matches out of " + total + " for our standard pattern.");
			  }
			}
		

As you can see, how you handle the result depends a lot on what type of result is produced.

For generic handling of results, including all the possible result extensions that might occur, DataCleaner employs a renderer framework which selects a result renderer according to type and precedence. If you need such generic functionality, take a look at the classes RendererBean, RendererFactory, Renderer and RenderingFormat.

One common requirement is to persisting it. We recommend doing this by means of Java's serialization, since analysis results are polymorphic and it's structure may be dependent on extensions. You can also device a more "structured" persistance scheme, but beware that it will require quite some stability in terms of which analyzers you add to your jobs.

So let's see how we use Java serialization. But unfortunately AnalysisResultFuture isn't serializable! There is however a class which shares the interface 'AnalysisResult' with 'AnalysisResultFuture', that is serializable, Namely 'SimpleAnalysisResult'. Let's see how to use it and serialize our result to a .analysis.result.dat file, (which DataCleaner can read):

			// make the result serializeable
			AnalysisResult analysisResult = resultFuture;
			analysisResult = new SimpleAnalysisResult(analysisResult.getResultMap());
			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my_result.analysis.result.dat"));
			oos.writeObject(analysisResult);
			oos.close();
		

And now let's, for example sake, also load our file by deserializing it. For this we need to use the ChangeAwareObjectInputStream class, which ensures backwards compatible deserialization of objects:

			ObjectInputStream ois = new ChangeAwareObjectInputStream(new FileInputStream("my_result.analysis.result.dat"));
			AnalysisResult analysisResult = (AnalysisResult) ois.readObject();
		

Now the result is restored and you can further work with it.