webservices/wsxml/inc/senfilterstatemachine.h
changeset 0 62f9d29f7211
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsxml/inc/senfilterstatemachine.h	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,402 @@
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Header declaration
+*
+*/
+
+
+
+
+
+
+
+
+#ifndef C_SEN_FILTER_STATE_MACHINE_H
+#define C_SEN_FILTER_STATE_MACHINE_H
+
+// INCLUDES
+
+#include <e32base.h>
+#include <e32std.h>
+#include <flogger.h>
+
+#include "SenBaseFragment.h"
+#include <SenXmlElement.h> // check if this include is needed(?)
+
+#include "SenPointerMap.h"
+
+#include "MSenFilterAction.h"
+#include "SenFilterCondition.h"
+
+// FORWARD DECLARATIONS
+
+class CSenFilterStateNode;
+class CSenFilterTableEntry;
+
+// CONSTANTS and DATA TYPES
+
+#define KBufferAllocationBlocks 10*1024
+
+typedef RPointerArray<CSenFilterStateNode> RStateNodeArray;
+
+//typedef RPointerArray<CSenFilterStateNode> RStateNodeArray;
+
+//typedef RSenPointerMap<TInt, CSenFilterTableEntry> RStateTablePointerMap;
+
+// CLASS DEFINITIONS
+
+/**
+ * @author lewontin
+ * 
+ * Implement an XML filter state machine. The supported filter syntax is a bit
+ * like XPath, but adds an || operator so you can select together multiple nodes
+ * below a specified node (e.g. "/a/b/c||d" selects both the c and d elements
+ * below /a/b). The goal is to avoid the necessity of returning intermediate
+ * nodes and then reparsing these one-by-one. Instead, the caller can collect
+ * these target values together (into a data structure) during a single parse.
+ * The parser will support the || operator on intermediate nodes, but this is
+ * not recommended as it makes the parser state table very big.
+ */
+class CSenFilterStateMachine : public CBase
+{
+
+private: // State type enumeration.
+
+    enum TStateType
+    {
+        EEnd = 0,
+        EStart
+    };
+
+
+    // Objects to build a tree representation of the filter state machine
+
+public: // Constructors and Destructors
+
+    IMPORT_C CSenFilterStateMachine();
+
+
+    IMPORT_C ~CSenFilterStateMachine();
+
+
+    /*
+     * The state tree is built up as a list of lists
+     * Each and filter adds a new list of states to the filter chain
+     * Each or filter appends a new set of states to the current list
+     */
+
+
+    /* private Vector filterChain = new Vector();
+     private TInt chainIndex = -1;
+     
+      
+      * Public methods to build filter chains. Parameters:
+      * aEvent -- the element name that causes this transition
+      *  aCondition -- further conditions for transition
+      
+     
+     // Add an AND filter: implements the "/" operator
+     
+     public void andFilter(const TDesC8& aEvent, FilterCondition aCondition, FilterAction aStartAction, FilterAction aEndAction) throws FilterException{
+        
+         filterChain.addElement(new Vector());
+         ++chainIndex;
+         orFilter(aEvent, aCondition, aStartAction, aEndAction);
+     }
+     
+     
+      * Add an OR filter: implements the "|" operator. Note that OR filters in
+      * non-terminal nodes blow up the deterministic state table exponentially so they should
+      * be used sparingly.
+      
+     
+     public void orFilter(const TDesC8& aEvent, FilterCondition aCondition, FilterAction aStartAction, FilterAction aEndAction) throws FilterException {
+         
+         if(chainIndex < 0){
+             throw new FilterException("ORFilter cannot be first in chain");
+         }
+         
+         // Get the current (possibly empty) list of OR states
+         Vector s = (Vector)filterChain.elementAt(chainIndex);
+        
+         if(chainIndex == 0){
+             // No previous states, just add a single new state node to the current list
+             s.addElement(new CSenFilterStateNode(aEvent, aCondition, aStartAction, aEndAction));
+         }
+         
+         else{
+             //Previous state(s) exist(s). Add a state transition from each previous state.
+             // Get the list of previous states 
+             Enumeration pStates = ((Vector)filterChain.elementAt(chainIndex - 1)).elements();
+             // For each previous state
+             while(pStates.hasMoreElements()){
+                 // Add a new state node to the current list
+                 CSenFilterStateNode iState = new CSenFilterStateNode(aEvent, aCondition, aStartAction, aEndAction);
+                 CSenFilterStateNode p = (CSenFilterStateNode)pStates.nextElement();
+                 iState.ipPrev = p;
+                 s.addElement(iState);
+             }
+         }
+     }*/
+
+
+    /* Add a node to the state tree */
+    IMPORT_C CSenFilterStateNode* AddChildLC(CSenFilterStateNode& aStartState, 
+                                             const TDesC8& aEvent,
+                                             const CSenFilterCondition& aCondition,
+                                             MSenFilterAction& aStartAction,
+                                             MSenFilterAction& aEndAction);
+
+    /* Add the root node to the state tree */
+    IMPORT_C CSenFilterStateNode* AddParentLC(const TDesC8& aEvent,
+                                              const CSenFilterCondition& aCondition,
+                                              MSenFilterAction& aStartAction,
+                                              MSenFilterAction& aEndAction);
+
+    /*
+     * Compile a state table by iterating over the state tree. Call this after building
+     * a filter chain from AND and OR filters.
+     */
+
+    /* public void compile(){
+         
+         if(filterChain == NULL){ //Already compiled
+             return;     
+         }
+         
+         Enumeration  chain = filterChain.elements();
+         while(chain.hasMoreElements()){
+             Enumeration iStates = ((Vector)chain.nextElement()).elements();
+             while(iStates.hasMoreElements()){
+                 CSenFilterStateNode node = (CSenFilterStateNode)iStates.nextElement();
+                 TInt p = 0;
+                 if(node.ipPrev != NULL){
+                     p = node.ipPrev.iState;
+                 }
+                 addEntry(p, node.iEvent, node.iCondition, node.iState, node.iStartAction, node.iEndAction);
+             }
+         }
+         //Allow the state tree to be garbage collected
+         filterChain = NULL;
+     }
+     */
+
+
+    /* Recursively compile the tree into a state table */
+    IMPORT_C void CompileL(CSenFilterStateNode& aStartNode);
+
+
+    // Public methods called by parser
+
+    IMPORT_C void StartElementL(const TDesC8& aName, 
+                                const RAttributeArray& aAttributes);
+
+    IMPORT_C void EndElementL(const TDesC8& aName);
+
+
+    // Register a new state by incrementing the state counter
+    // and returning this counter as unique ID for this session
+    const TInt RegisterState();
+
+
+    const TInt States() const;
+
+
+private:
+
+    // Private method to add an entry to the state table
+    void AddEntryL(TInt aInitialState, 
+                   const TDesC8& aEvent, 
+                   const CSenFilterCondition& aCondition, 
+                   TInt aNextState, 
+                   MSenFilterAction& aStartAction, 
+                   MSenFilterAction& aEndAction);
+
+
+    // Create an unique key for state table node
+    const TUint16 GetStateKeyL(TInt aState, 
+                               const TDesC8& aEvent, 
+                               TInt aStart);
+
+
+private:
+
+    // Methods to run the state machine
+    const TInt TransitionL(TInt aState, 
+                           const TDesC8& aEvent, 
+                           TInt start, 
+                           const RAttributeArray& aAttributes);
+
+
+
+private:
+
+    /**
+     * File logger.
+     *
+     */
+    RFileLogger* Log() const;
+
+
+private:
+
+    //The filter state machine state table
+    RSenPointerMap<TUint16, CSenFilterTableEntry> iStateTable;
+
+    TInt iFilterState;
+
+    TInt iStates; // Counter of all states
+
+
+    RFileLogger iLog;
+
+}; // end class CSenFilterStateMachine
+
+
+// ----------------------------------------
+//
+// Declaration of class CSenFilterStateNode
+//
+// ----------------------------------------
+
+/**
+     * A node in the state tree
+     * Parent      -  points to the previous state in the diagram
+     * Children    -  set of successor states in the diagram
+     * State       -  state number for this state
+     * Event       -  event that triggers transition from ipPrev to this
+     * Condition   -  additional test on transition
+     * StartAction - 
+     * EndAction   - 
+     */
+class CSenFilterStateNode : public CBase
+{
+
+public:
+
+    IMPORT_C CSenFilterStateNode(const TDesC8& aEvent, 
+                                 const CSenFilterCondition& aCondition, 
+                                 MSenFilterAction& aStartAction, 
+                                 MSenFilterAction& aEndAction,
+                                 CSenFilterStateMachine& aStateMachine);
+
+    IMPORT_C CSenFilterStateNode(const CSenFilterStateNode& aFilterStateNode);
+
+
+    IMPORT_C ~CSenFilterStateNode();
+
+
+public:
+
+    IMPORT_C TInt State() const;
+
+
+    IMPORT_C TDesC8 Event() const;
+
+
+    IMPORT_C CSenFilterCondition Condition() const;
+
+
+    IMPORT_C MSenFilterAction& StartAction() const;
+
+
+    IMPORT_C MSenFilterAction& EndAction() const;
+
+
+    IMPORT_C CSenFilterStateNode& Parent() const;
+
+
+    IMPORT_C RStateNodeArray Children() const;
+
+
+    IMPORT_C void SetParent(CSenFilterStateNode& aNode);
+
+
+private:
+
+    /**
+     * File logger.
+     *
+     */
+    RFileLogger* Log() const;
+
+
+private:
+
+    TInt iState; // Node index
+    TDesC8 iEvent;
+    CSenFilterCondition iCondition;
+    MSenFilterAction& iStartAction;
+    MSenFilterAction& iEndAction;
+
+    CSenFilterStateNode* ipPrev;
+
+    RStateNodeArray iChildren;
+
+    RFileLogger iLog;
+
+}; // end class CSenFilterStateNode
+
+
+// -----------------------------------------
+//
+// Declaration of class CSenFilterTableEntry
+//
+// -----------------------------------------
+
+class CSenFilterTableEntry : public CBase
+{
+
+public:
+
+    CSenFilterTableEntry(TInt aNewState, 
+                         const CSenFilterCondition& aCondition,
+                         MSenFilterAction& aAction);
+
+
+    ~CSenFilterTableEntry();
+
+public:
+
+    TInt NewState() const;
+
+
+    CSenFilterCondition Condition() const;
+
+
+    MSenFilterAction& Action() const;
+
+
+private:
+
+    /**
+     * File logger.
+     *
+     */
+    RFileLogger* Log() const;
+
+
+private:
+
+    TInt iNewState;
+    CSenFilterCondition iCondition;
+    MSenFilterAction& iAction;
+
+    RFileLogger iLog;
+
+}; // end class CSenFilterTableEntry
+
+
+#endif // C_SEN_FILTER_STATE_MACHINE_H
+