[Mondrian] Proposal for adding result post processor extension tospi

Julian Hyde julianhyde at speakeasy.net
Mon Oct 8 14:16:57 EDT 2007


I think you could do this non-invasively, using wrapper classes. There's no
need for an SPI because you don't need to get 'inside' mondrian.
 
Implement another class which implements mondrian.olap.Result and which
wraps the actual RolapResult returned from the query. You can re-order axes,
eliminate positions, etc. etc. in your wrapper class without touching the
real Result.
 
How are you connecting to the mondrian API? If you are connecting directly,
adding the wrapper is easy:
 
Connection connection;
Query query;
Result result = connection.executeQuery(query);
Result wrappedResult = new MyResult(result, query);
 
If you are working with XMLA, you may need to create your own implementation
of Connection class which does the wrapping automatically.
 
Julian
 
  _____  

From: mondrian-bounces at pentaho.org [mailto:mondrian-bounces at pentaho.org] On
Behalf Of Ajit Vasudeo Joglekar
Sent: Monday, October 08, 2007 2:38 AM
To: mondrian at pentaho.org
Subject: [Mondrian] Proposal for adding result post processor extension
tospi




We have a scenario where we need to filter out rows and columns based on
criteria such as, is the cell value result of a literal calculated member
evaluation and whether the next position on the same axis isNull 

Adding a extension point in RolapConnection (similar to
DynamicSchemaProcessor) as below will allow post processing of the generated
result. ResultPostProcessor implementation class could be a connection
property similar to the DynamicSchemaProcessor 

In RolapConnection - "public Result execute(Query query)" method 


            for (int i = 0; i < query.axes.length; i++) { 
                QueryAxis axis = query.axes[i]; 
                if (axis.isNonEmpty()) { 
                    result = new NonEmptyResult(result, query, i); 
                } 
            } 
+            try { 
+                final Class<ResultPostProcessor> clazz = 
+                (Class<ResultPostProcessor>) 
+                    Class.forName(resultPostProcessorName); 
+                final Constructor<ResultPostProcessor> ctor = 
+                clazz.getConstructor(); 
+                final ResultPostProcessor resultPostProc =
ctor.newInstance(); 
+                result = resultPostProc.postProcessResult(result, query); 
+ 
+            } catch (Exception e) { 
+                throw Util.newError(e, "loading ResultPostProcessor " 
+                + resultPostProcessorName); 
+            } 
            if (LOGGER.isDebugEnabled()) { 
                StringWriter sw = new StringWriter(); 
                PrintWriter pw = new PrintWriter(sw); 
                result.print(pw); 
                pw.flush(); 
                LOGGER.debug(sw.toString()); 
            } 
            query.setQueryEndExecution(); 
            return result; 

To effectively make use of information contained in the Result instance in
the post processor it will be necessary to make certain class methods,
members accessible as follows 

public abstract class ResultBase 
        protected final Axis[] axes; // remove final 


class RolapCell implements Cell { // make public 

RolapCell 
private Member[] getMembers() { // make public 


The ResultPostProcessor could be a simple interface as below 

public interface ResultPostProcessor { 
    public Result postProcessResult(Result result, Query query); 
} 

========================= 


Requesting comments, suggestions 

Thanks, 
-Ajit 













-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.pentaho.org/pipermail/mondrian/attachments/20071008/de210c06/attachment.html 


More information about the Mondrian mailing list