import logging
import appconfig as config
import os
from RenderTemplate import renderLayout, renderTemplate
from CommandUtil import dispatchCommand,getUrlParams, __get_process_instance_Id__, authenticateIntegration
from orangescape.model.server.SearchExecution import SearchExecution
from orangescape.model.server.UserAuthentication import UserAuthentication
from orangescape.model.server.Constants import HTML_RESPONSE, JSON_RESPONSE, CSV_RESPONSE, EDITOR, INBOX, WORKTOP, REPORT, SEARCH
from orangescape.model.server.util.ServerUtil import _get_class, geFinalEditorFormName, getFinalInboxFormName

from orangescape.model.server.util.formserialization import getJsonString
from orangescape.model.server.util.menuserialization import getMenuHtmlString, getMenuJsonString
from orangescape.model.server.util.InboxSerialize import getInboxJson,getInboxCsv
from Validate import validateUser,validateCreate,validateUrl,validateUser_Read
from orangescape.model.engine.exception.Error import ReportEngineError
from orangescape.model.engine.exception.ErrorMessage import Report1001, Report1002
from cgi import parse_qs

class BaseCommandFactory():
    userid=None
    session=None

    def setUserId(self, userid):
        self.userid = userid
        userins=self.getSession().get(self.userid,self.getSession().getApplication().getSheetMetadata('User'))
        self.getSession().setUser(userins)

    def setSession(self,session):
        self.session=session

    def getSession(self):
        return self.session

    def getMetadataType(self):
        return "1"

    def __commit__(self):
        self.getSession().commit()

    def rollback(self):
        self.getSession().rollback()

    def new(self,metadatatype,applicationid,parentsheetmetadataid,taskid,sheetmetadataid):
        query_string=self.request.query_string
        url=getUrlParams(self.request.path)
        metadataType=url.pop(0)
        versionId=url[0]
        applicationObj = self.getSession().getApplication()
        modifiedIn = url[2]
        params = self.getQueryStringParams(query_string)

        self.getSession().setModifiedIn(modifiedIn)
        sheetMetadataId=url.pop()
        sheetMetadata=applicationObj.getSheetMetadataById(sheetMetadataId);

        #when using short cut to create new
        if params.__contains__('ShortCut'):
            if not sheetMetadata.getPublicCellMetadataDict().__contains__('ShortCut'):
                del params['ShortCut']

        #get root Sheet and formName
        actDef=sheetMetadata.getActivityDefinitionById(modifiedIn)
        formName = self.getEditorFormName(params, actDef, sheetMetadata)

        sheet = dispatchCommand(self.getSession(),'new', sheetMetadata, params)
        self.__commit__()

        #common method which is overridden in silverlight preview
        jsonstr = self.returnResponseOnNew(self.getSession(), sheet, formName)


        if self.getMimeType()==JSON_RESPONSE:
            self.response.out.write(jsonstr)
        else:
            paramStr = "mimetype=text/html"
            if query_string.__contains__("form="):
                paramStr += "&"+query_string[query_string.index("form="):]
            elif query_string.__contains__("editorGridViewId="):
                #for backward compatibilty
                paramStr += "&"+query_string[query_string.index("editorGridViewId="):]
            tempJson = jsonstr[jsonstr.find("root")+7:]

            if self.request.params.get("theme") == "off":
                paramStr+= "&theme=off"

            self.redirect(self.request.path+"/"+tempJson[0:tempJson.index(",")-1]+"?"+paramStr,True)

    def create(self,metadatatype,applicationid,parentsheetmetadataid,taskid,sheetmetadataid,url):
        """POST /Instances: Create a new item."""
        query_string=self.request.query_string
        url=getUrlParams(self.request.path)
        metadataType=url.pop(0)
        versionId=url[0]
        modifiedIn = url[2]
        rootSheetMetadataId=url[3]
        rootSheetId = url[4]

        self.getSession().setModifiedIn(modifiedIn)

        applicationObj = self.getSession().getApplication()
        #get root sheetmetadata and root sheet instance. this will be serialized in the end to the ui.
        rootSheetMetadata=applicationObj.getSheetMetadataById(rootSheetMetadataId)
        sheet=self.getSession().get(rootSheetId,rootSheetMetadata)
        piId = __get_process_instance_Id__(self.getSession(), modifiedIn, rootSheetMetadataId, rootSheetId)
        validateUser(self.getSession(),applicationObj,url,sheet,piId)

        params = self.getQueryStringParams(query_string)
        params.update(self.request.params)
        sheetMetadataId=url.pop()
        referenceKeyId=url.pop()
        parentSheetId=url.pop()
        parentSheetMetadataId=url.pop()

        parentSheetMetadata=applicationObj.getSheetMetadataById(parentSheetMetadataId)
        parentSheet=self.getSession().get(parentSheetId,parentSheetMetadata)
        sheetMetadata=applicationObj.getSheetMetadataById(sheetMetadataId);
        referenceKeyCellMetadata = sheetMetadata.getCellMetadataById(referenceKeyId)
        validateCreate(url,sheetMetadata,parentSheetMetadata,referenceKeyCellMetadata)
        if(len(url)>0):
            validateUrl(url,applicationObj,parentSheet,parentSheetMetadata,self.getSession())

        params['ModifiedIn'] = piId

        self.checkLockedBy(sheet)
        actDef=rootSheetMetadata.getActivityDefinitionById(modifiedIn)
        formName = self.getEditorFormName(params, actDef, rootSheetMetadata)

        dispatchCommand(self.getSession(),'create', parentSheet,referenceKeyCellMetadata,params)
        self.__commit__()
        response = self.returnResponse(self.getSession(), sheet, formName)
        self.response.out.write(response)

    def read(self,metadatatype,applicationid,parentsheetmetadataid,taskid,sheetmetadataid,url):
        """GET /Instances/id: Show a specific item."""
        query_string = self.request.query_string
        url=getUrlParams(self.request.path)
        metadataType=url.pop(0)
        #get the last item(ie the sheetmetadataid) and get the sheet
        versionId=url[0]
        modifiedIn = url[2]
        rootSheetId = url[4]
        rootSheetMetadataId=url[3]
        sheetId=url.pop()
        sheetMetadataId=url.pop()

        applicationObj = self.getSession().getApplication()
        self.getSession().setModifiedIn(modifiedIn)
        #sheetMetadata=context.get('SheetMetadata', sheetMetadataId);
        sheetMetadata=applicationObj.getSheetMetadataById(sheetMetadataId)
        sheet=self.getSession().get(sheetId, sheetMetadata)
#        validateUser(self.getSession(),applicationObj,url,sheet)
        validateUser_Read(self.getSession(),applicationObj,url,sheet)
        if(len(url)>0):
            validateUrl(url,applicationObj,sheet,sheetMetadata,self.getSession())

        #get root Sheet and formName
        rootSheetMetadata=applicationObj.getSheetMetadataById(rootSheetMetadataId)
        sheet=self.getSession().get(rootSheetId,rootSheetMetadata)
        actDef=rootSheetMetadata.getActivityDefinitionById(modifiedIn)
        params = self.getQueryStringParams(query_string)
        formName = self.getEditorFormName(params, actDef, rootSheetMetadata)
        #get the sheet instance and call engine to evaluate the formula
        dispatchCommand(self.getSession(),'read', sheetId, sheetMetadata)
        response = self.returnResponse(self.getSession(), sheet, formName)
        self.response.out.write(response)

    def update(self,metadatatype,applicationid,parentsheetmetadataid,taskid,sheetmetadataid,url):
        """http://localhost:8080/v100/s102/a501/s102/agtvcmFuZ2VzY2FwZXISCxIMRHluYW1pY01vZGVsGAsM?_method=PUT&c130=2"""
        query_string = self.request.query_string
        url=getUrlParams(self.request.path)
        metadataType=url.pop(0)
        modifiedIn = url[2]
        versionId=url[0]
        parentSheetMetadataId=url[1]
        activityDefid=url[2]

        rootSheetId = url[4]
        rootSheetMetadataId=url[3]

        applicationObj = self.getSession().getApplication()
        #get the last item(ie the sheetmetadataid) and get the sheet
        instanceId = url.pop()
        metadataId = url.pop()
        rootSheetMetadata=applicationObj.getSheetMetadataById(rootSheetMetadataId)
        sheet=self.getSession().get(rootSheetId,rootSheetMetadata)
        self.getSession().setModifiedIn(modifiedIn)
        piId = __get_process_instance_Id__(self.getSession(), modifiedIn, rootSheetMetadataId, rootSheetId)
        validateUser(self.getSession(),applicationObj,url,sheet,piId)

        metadata = applicationObj.getSheetMetadataById(metadataId)
        instance=self.getSession().get(instanceId, metadata)
        if(len(url)>0):
            validateUrl(url,applicationObj,instance,metadata,self.getSession())
        #create an instance and call engine to evaluate the formula
        params = self.getQueryStringParams(query_string)

        params['ModifiedIn'] = piId

        #get root Sheet and formName
        rootSheetMetadata=applicationObj.getSheetMetadataById(rootSheetMetadataId)
        sheet=self.getSession().get(rootSheetId,rootSheetMetadata)
        self.checkLockedBy(sheet)
        actDef=rootSheetMetadata.getActivityDefinitionById(modifiedIn)
        formName = self.getEditorFormName(params, actDef, rootSheetMetadata)

        dispatchCommand(self.getSession(), 'update', instance, params)
        self.__commit__()
        response = self.returnResponse(self.getSession(), sheet, formName)
        self.response.out.write(response)

    #name delete aleady exist in webapp.RequestHandler,so we are using deleteAction
    def deleteAction(self,metadatatype,applicationid,parentsheetmetadataid,taskid,sheetmetadataid,url):
        """DELETE /Instances/id: Delete an existing item."""
        query_string = self.request.query_string
        url=getUrlParams(self.request.path)
        metadataType=url.pop(0)
        modifiedIn = url[2]
        rootSheetMetadataId=url[3]
        rootSheetId = url[4]

        applicationObj = self.getSession().getApplication()
        #get the last item(ie the sheetmetadataid) and get the sheet
        instanceId = url.pop()
        metadataId = url.pop()
        rootSheetMetadata=applicationObj.getSheetMetadataById(rootSheetMetadataId)
        sheet=self.getSession().get(rootSheetId,rootSheetMetadata)

        self.getSession().setModifiedIn(modifiedIn)
        piId = __get_process_instance_Id__(self.getSession(), modifiedIn, rootSheetMetadataId, rootSheetId)
        validateUser(self.getSession(),applicationObj,url,sheet,piId)
        metadata = applicationObj.getSheetMetadataById(metadataId)
        instance=self.getSession().get(instanceId, metadata)
        if(len(url)>0):
            validateUrl(url,applicationObj,instance,metadata,self.getSession())
        #create an instance and call engine to evaluate the formula
        sheet = dispatchCommand(self.getSession(), 'delete', instance)
        self.__commit__()

        if rootSheetId != instanceId:
            #get root Sheet and formName
            rootSheetMetadata=applicationObj.getSheetMetadataById(rootSheetMetadataId)
            sheet=self.getSession().get(rootSheetId,rootSheetMetadata)

            actDef=rootSheetMetadata.getActivityDefinitionById(modifiedIn)
            params = self.getQueryStringParams(query_string)
            formName = self.getEditorFormName(params, actDef, rootSheetMetadata)
            response = self.returnResponse(self.getSession(), sheet, formName)
            self.response.out.write(response)

    def invoke(self,metadatatype,applicationid,parentsheetmetadataid,taskid,sheetmetadataid,url,updateJson=None):
        """http://localhost:8080/v100/s102/a501/s102/agtvcmFuZ2VzY2FwZXISCxIMRHluYW1pY01vZGVsGAsM?_method=PUT&c130=2"""
        url=getUrlParams(self.request.path)
        if updateJson:
            newDict = {}
            newDict.update(self.request.params)
            newDict['updateJson'] = updateJson
            jsonStr = self.performInvoke(url, newDict)
        else:
            jsonStr = self.performInvoke(url, self.request.params)
        self.response.out.write(jsonStr)

    def performInvoke(self, url, values):
        params = {}
        for key, value in values.iteritems():
            params[key] = value
        metadataType=url.pop(0)
        modifiedIn = url[2]
        applicationObj=self.getSession().getApplication()
        self.getSession().setModifiedIn(modifiedIn)
        #get root Sheet
        rootSheetMetadataId=url[3]
        rootSheetId = url[4]
        rootSheetMetadata = applicationObj.getSheetMetadataById(rootSheetMetadataId)
        rootSheet = self.getSession().get(rootSheetId, rootSheetMetadata)
        piId = __get_process_instance_Id__(self.getSession(), modifiedIn, rootSheetMetadataId, rootSheetId)
        validateUser(self.getSession(),applicationObj,url,rootSheet,piId)

        #get formName
        actDef=rootSheetMetadata.getActivityDefinitionById(modifiedIn)
        formName = self.getEditorFormName(params, actDef, rootSheetMetadata)
        params['form'] = formName

        params['rootSheetMetadataId'] = rootSheetMetadataId
        params['ModifiedIn'] = piId

        if (len(url))%3==2:
            instanceId = url.pop()
            metadataId = url.pop()
            metadata = applicationObj.getSheetMetadataById(metadataId)
            instance = self.getSession().get(instanceId, metadata)
            if(len(url)>0):
                validateUrl(url,applicationObj,instance,metadata,self.getSession())
            self.checkLockedBy(instance)
            #update modifiedIn for the root object
            dispatchCommand(self.getSession(), 'update', instance, {'ModifiedIn':params['ModifiedIn']})
            res = dispatchCommand(self.getSession(), 'invoke',metadata, params, instance)
        elif (len(url))%3==1:
            "Creating a new object get the to be created metadataId and reference cell"
            metadataId = url.pop()
            referenceCellId = url.pop()
            parentSheetId = url.pop()
            parentMetadataId = url.pop()
            metadata = applicationObj.getSheetMetadataById(metadataId)
            parentMetadata = applicationObj.getSheetMetadataById(parentMetadataId)
            parentSheet = self.getSession().get(parentSheetId, parentMetadata)
            manyToOneList = [refCell for refCell in metadata.getManyToOneList() if str(refCell.getSheetId()).__eq__(referenceCellId)]
            if(len(url)>0):
                validateUrl(url, applicationObj, parentSheet, parentMetadata, self.getSession())
            if len(manyToOneList)>0:
                referenceCell = manyToOneList[0]
            else:
                raise Exception("Couldn't find the reference cell id "+referenceCellId)
            self.checkLockedBy(parentSheet)
            #update modifiedIn for the root object
            dispatchCommand(self.getSession(), 'update', parentSheet, {'ModifiedIn':params['ModifiedIn']})
            sheet = dispatchCommand(self.getSession(), 'invoke', metadata, params, parentSheet, referenceCell)

        self.__commit__()
        response = self.returnResponse(self.getSession(), rootSheet, formName)
        return response

    def processLogin(self, metadatatype=None, applicationid=None):
        authInstance = _get_class(config.AUTHENTICATION)()
        authInstance.processLogin(self)

    def renderLogin(self, metadatatype=None, applicationid=None):
        authInstance = _get_class(config.AUTHENTICATION)()
        authInstance.renderLogin(self)

    def logout(self,metadatatype,applicationid):
        self.redirect(UserAuthentication(self.getSession()).logOutUser(self.userid))

    def renderWorktop(self,metadatatype,applicationid):
        queryString = self.request.query_string
        userMetadata=self.getSession().getApplication().getSheetMetadata('User')
        workflowBranch=userMetadata.getWorkFlowRoot()
        startActivity=workflowBranch.getActivityDefinitionList()[0]
        jsonUrl = '/'+self.getSession().getApplication().getSheetId()+'/'+metadatatype+'/'+userMetadata.getSheetId()+'/'+startActivity.getSheetId()+'/'+userMetadata.getSheetId()+'/'+self.userid
        if queryString.__contains__('MetadataId'):
            jsonUrl = jsonUrl+"?"+queryString

        params = self.getQueryStringParams(queryString)
        templateName = self.getTemplateName(params)
        response = renderLayout(self, WORKTOP, jsonUrl, "worktop/worktop.jstl", templateName)
        self.response.out.write(response)

    def renderHome(self,metadatatype=None,applicationid=None):
        applicationObj = self.getSession().getApplication()
        if not metadatatype:
        	metadatatype = '1'
        if applicationObj.getSheetMetadataDict().has_key('UserChanges') and self.getSession().getUser().getValue('LastLoggedinTime') is None and self.getSession().getUser().getValue('Current') is not None:
            usrChgMetadata = applicationObj.getSheetMetadata('UserChanges')
            usrChgInstance = self.getSession().get(self.getSession().getUser().getValue('Current'), usrChgMetadata)
            if usrChgInstance.getValue("FirstTimeLogin"):
                self.redirect('/'+applicationObj.getSheetId()+'/'+metadatatype+'/'+usrChgMetadata.getSheetId()+'/'+usrChgInstance.getValue('Status')+'/'+usrChgMetadata.getSheetId()+'/'+usrChgInstance.getSheetId()+'?mimetype=text/html')
                return
        if config.HOMEPAGE== 'myaccount':
            userMetadata=applicationObj.getSheetMetadata('User')
            userins=self.getSession().get(self.userid,userMetadata)
            self.redirect('/'+applicationObj.getSheetId()+'/'+metadatatype+'/'+userMetadata.getSheetId()+'/'+userins.getValue('Status')+'/'+userMetadata.getSheetId()+'/'+userins.getSheetId()+'?mimetype=text/html')
        else:
            self.renderWorktop(metadatatype, applicationid)

    def menu(self,metadatatype,applicationid):
        if self.getMimeType()==JSON_RESPONSE:
            menuStr = getMenuJsonString(self.getSession())
            callbackName = self.getCallBackMethodName()
            if callbackName:
                menuStr = callbackName+"("+menuStr+")"
        else:
            menuStr = getMenuHtmlString(self.getSession(), self.getMetadataType())
        self.response.headers['ETag'] = self.getSession().getUser().getValue("UserLoginModel")
        self.response.headers['Cache-Control'] = 'max-age=3600'
        self.response.out.write(menuStr)

    def authenticate(self, metadatatype, applicationid):
        authorizationToken = self.request.get("Authorization")
        responseStr = "{'error':'Unable to authenticate.Auth info not present as part of the header.'}"
        if authorizationToken:
            responseDict= authenticateIntegration(self.getSession(), authorizationToken, self)
            if responseDict.has_key('error'):
                responseStr = str(responseDict)
            else:
                responseStr = getMenuJsonString(self.getSession())
        callbackName = self.getCallBackMethodName()
        if callbackName:
                responseStr = callbackName+"("+responseStr+")"
        self.response.out.write(responseStr)

    def triggersla(self,metadatatype,applicationid):
        self.userid = 'guest'
        userins=self.getSession().get(self.userid, self.getSession().getApplication().getSheetMetadata('User'))
        self.getSession().setUser(userins)
        dispatchCommand(self.getSession(), 'triggerSLA_Action')
        self.__commit__()

#***************************************************************** helper methods *******************************************************

    def getMimeType(self):
        return self.request.accept.best_matches()[0]

    def getCallBackMethodName(self):
        return self.request.get("callback")

    def getTemplateName(self, params):
        if params.__contains__('template') and len(params['template']) > 0:
            return params['template']
        return "index.html"

    def getEditorFormName(self, params, actDef, sheetMetadata):
        if params.__contains__('form') and len(params['form']) > 0:
            formName = params['form']
            del params['form']
            return formName
        #************************** for backward compatibility *************************
        if params.__contains__('editorGridViewId') and len(params['editorGridViewId']) > 0:
            formId = params['editorGridViewId']
            del params['editorGridViewId']
            gridViewDict = sheetMetadata.getGridViewList()
            if gridViewDict.has_key(formId):
                return gridViewDict.get(formId)
        #*********************************************************************************
        return geFinalEditorFormName(actDef)


    def getInboxFormName(self, params, actDef, sheetMetadata):
        if params.__contains__('form') and len(params['form']) > 0:
            formName = params['form']
            del params['form']
            return formName
        return getFinalInboxFormName(actDef)

    def getSearchEditorFormName(self, params, search, sheetMetadata):
        if params.__contains__('form') and len(params['form']) > 0:
            formName = params['form']
            del params['form']
            return formName
        return geFinalEditorFormName(search)

    def getSearchFormName(self, params, search, sheetMetadata):
        if params.__contains__('form') and len(params['form']) > 0:
            formName = params['form']
            del params['form']
            return formName
        #************************** for backward compatibility *************************
        if params.__contains__('inboxGridViewId') and len(params['inboxGridViewId']) > 0:
            formId = params['inboxGridViewId']
            del params['inboxGridViewId']
            qGridViewDict = sheetMetadata.getQGridViewList()
            if qGridViewDict.has_key(formId):
                return qGridViewDict.get(formId)
        #*********************************************************************************
        return getFinalInboxFormName(search)

    def checkLockedBy(self, sheet):
        if config.env==config.SL:
            return True
        metadata = sheet.getSheetMetadata()
        if metadata.getPublicCellMetadataDict().has_key('LockedBy'):
            if sheet.getValue('LockedBy') and sheet.getValue('LockedBy') != self.userid:
                lockedByUser = self.getSession().getIfExists(sheet.getValue('LockedBy'), self.getSession().getApplication().getSheetMetadata('User'))
                modifiedIn = sheet.getValue('ModifiedIn')
                msg = ''
                if modifiedIn:
                    piMetadata = self.getSession().getApplication().getSheetMetadata('ProcessInstance')
                    pi = self.getSession().get(modifiedIn, piMetadata)
                    activityName = pi.getValue('ActivityName')
                    msg = ' in the process %s'%activityName
                if lockedByUser:
                    raise Exception('The record %s is locked by %s%s'%(sheet.getSheetName(), lockedByUser.getSheetName(), msg))
                raise Exception('The record %s is locked by %s%s'%(sheet.getSheetName(), sheet.getValue('LockedBy'), msg))
            if not sheet.getValue('LockedBy'):
                dispatchCommand(self.getSession(),'update', sheet, {'LockedBy':self.userid})
        return True

    def getQueryStringParams(self, values):
        params = dict()
        if values:
            params = parse_qs(values, True)
            if params.__contains__('mimetype'):
                del params['mimetype']
            for key in params.keys():
                if key=='callback' or key.startswith('_'):
                    del params[key]
                    continue
                value = params[key]
                if len(value)>1:
                    params[key] = value
                else:
                    params[key] = value[0]

            if params.__contains__('theme'):
                del params['theme']
        return params

    def returnResponseOnNew(self, session, root, formName):
        jsonStr = getJsonString(session, root, formName)
        return self.getJsonForJsonp(jsonStr)

    def returnResponse(self, session, root, formName):
        if self.getMimeType()==JSON_RESPONSE:
            jsonStr = getJsonString(session, root, formName)
            return self.getJsonForJsonp(jsonStr)
        elif self.getMimeType()==HTML_RESPONSE:
            jsonUrl = self.request.path#+"?form="+formName
            params = self.getQueryStringParams(self.request.query_string)
            templateName = self.getTemplateName(params)
            return renderLayout(self, EDITOR, jsonUrl, root.getSheetMetadata().getSheetName()+"/"+formName+".jstl", templateName, formName)

    def returnSearchResponse(self, sheetmetadata, searchDef, formName, pageNumber, pageCount, typeName, searchResult=None, serializeChildRecord=False, totalCount = 0):
        if self.getMimeType()==JSON_RESPONSE and searchResult is not None:
            displayCellName = "SheetName"
            displayCell = searchDef.getDisplayCell()
            if displayCell:
                displayCellName = displayCell.getCellName()

            jsonStr = getInboxJson(self.getSession(), sheetmetadata, searchResult, displayCellName, serializeChildRecord, totalCount)
            return self.getJsonForJsonp(jsonStr)
        elif self.getMimeType()==CSV_RESPONSE and searchResult:
            values=self.getQueryStringParams(self.request.query_string)
            columnNameList= list()
            if values.__contains__('header'):
            	#columnNameList = values['header'][1:-1].split(',')
                columnNameList=eval(values['header'])
            csvStr = getInboxCsv(self.getSession(), sheetmetadata, searchResult, columnNameList)
            self.response.headers['Content-Type'] = CSV_RESPONSE
            self.response.headers['Content-Disposition'] = 'inline; filename="%s.csv"' % sheetmetadata.getSheetName()
            return csvStr
        elif self.getMimeType()==HTML_RESPONSE:
            values=self.getQueryStringParams(self.request.query_string)
            url_path = self.request.path
            #need to handled if page number and page size is not specified(backward compatibility)
            if pageNumber is None:
                url_path += "/p1/"
            if pageCount is None:
                pageCount=20
                if searchDef.getItemsPerPage():
                    pageCount = int(searchDef.getItemsPerPage())
                url_path += str(pageCount)

            #for user input(dynamic parameters,starts with $)need to be part of filter data
            queryStringBuffer = list()
            queryStringBuffer.append("{")
            for key in values:
                if key.startswith("$"):
                    queryStringBuffer.append("'"+key[1:]+"'")
                    queryStringBuffer.append(":")
                    queryStringBuffer.append("'"+values.get(key)+"'")
                elif key == "asc" or key == "desc":
                    queryStringBuffer.append("'"+key+"'")
                    queryStringBuffer.append(":")
                    queryStringBuffer.append(values.get(key).replace('"', '\''))
            queryStringBuffer.append("}")
            queryString = ''.join(queryStringBuffer)
            templateName = self.getTemplateName(values)
            return renderLayout(self, typeName, url_path, sheetmetadata.getSheetName()+"/"+formName+".jstl", templateName, formName, queryString)

    def getJsonForJsonp(self, jsonStr):
        callbackName = self.getCallBackMethodName()
        if callbackName:
            jsonStr = callbackName+"("+jsonStr+")"
        return jsonStr

# ***************************************** commandfactory for connect dialog and activty *************************************************

    def readforReport(self,metadatatype,applicationid,sheetmetadataid,searchdefinitionid,pageNumber=None,pageCount=None):
        applicationObj=self.getSession().getApplication()
        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        searchDef = sheetmetadata.getSearchDefinitionById(searchdefinitionid)
        params = self.getQueryStringParams(self.request.query_string)
        formName = self.getSearchFormName(params, searchDef, sheetmetadata)
        if self.getMimeType()==HTML_RESPONSE:
            self.response.out.write(self.returnSearchResponse(sheetmetadata, searchDef, formName, pageNumber, pageCount, REPORT))
        else:
            baseQuery = list()
            userSheetMetadata=self.getSession().getApplication().getSheetMetadata('User')
            searchExe=SearchExecution(self.getSession())
            params = self.getQueryStringParams(self.request.query_string)
            searchResult = searchExe.execteSearch(sheetmetadata,userSheetMetadata,self.getSession().getUser(), baseQuery, searchDef, pageNumber, pageCount, True, params)
            totalCount = searchExe.getTotalCount()
            jsonStr = self.returnSearchResponse(sheetmetadata, searchDef, formName, pageNumber, pageCount, REPORT, searchResult, True, totalCount)
            self.response.out.write(jsonStr)

    def readforMasterReport(self,metadatatype,applicationid,sheetmetadataid,searchdefinitionid,mastersearchid):
        applicationObj=self.getSession().getApplication()
        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        searchDef = sheetmetadata.getSearchDefinitionById(mastersearchid)
        baseQuery = list()
        userSheetMetadata=self.getSession().getApplication().getSheetMetadata('User')
        searchExe=SearchExecution(self.getSession())
        params = self.getQueryStringParams(self.request.query_string)
        searchResult = searchExe.execteSearch(searchDef.getReferredSheetMetadata(),userSheetMetadata,self.getSession().getUser(), baseQuery, searchDef, None, None, False, params)
        totalCount = searchExe.getTotalCount()
        if self.getMimeType()==JSON_RESPONSE:
            jsonStr = self.returnSearchResponse(searchDef.getReferredSheetMetadata(), searchDef, None, None, None, REPORT, searchResult, False, totalCount)
            self.response.out.write(jsonStr)

    def readforInbox(self,metadatatype,applicationid,sheetmetadataid,activitydefinitionid,pageNumber=None,pageCount=None,SecondaryUser=None):
        query_string=self.request.query_string
        urlParamList=getUrlParams(self.request.path)
        jsonStr=  self.performReadForInbox(urlParamList,query_string, pageNumber, pageCount, SecondaryUser)
        self.response.out.write(jsonStr)

    def readforInstanceReport(self,metadatatype,applicationid,parentsheetmetadataid,searchdefinitionid,sheetmetadataid,sheetid):
        applicationObj = self.getSession().getApplication()
#        validateUser_Read(self.getSession(),applicationObj,url,sheet)
#        if(len(url)>0):
#            validateUrl(url,applicationObj,sheet,sheetMetadata,self.getSession())

        #get root Sheet and formName
        rootSheetMetadata=applicationObj.getSheetMetadataById(sheetmetadataid)
        sheet=self.getSession().get(sheetid,rootSheetMetadata)
        searchDef=rootSheetMetadata.getSearchDefinitionById(searchdefinitionid)
        params = self.getQueryStringParams(self.request.query_string)
        formName = self.getSearchEditorFormName(params, searchDef, rootSheetMetadata)
        #get the sheet instance and call engine to evaluate the formula
        dispatchCommand(self.getSession(),'read', sheetid, rootSheetMetadata)
        response = self.returnResponse(self.getSession(), sheet, formName)
        self.response.out.write(response)

    def invokeforReport(self,metadatatype,applicationid,parentsheetmetadataid,searchdefinitionid,sheetmetadataid,sheetid,updateJson=None):
        url=getUrlParams(self.request.path)
        params = {}
        for key, value in self.request.params.iteritems():
            params[key] = value
        metadataType=url.pop(0)
        applicationObj=self.getSession().getApplication()
        #get root Sheet
        rootSheetMetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        rootSheet = self.getSession().get(sheetid, rootSheetMetadata)
        validateUser(self.getSession(),applicationObj,url,rootSheet)

        #get formName
        searchDef=rootSheetMetadata.getSearchDefinitionById(searchdefinitionid)
        formName = self.getSearchEditorFormName(params, searchDef, rootSheetMetadata)
        params['form'] = formName
        params['rootSheetMetadataId'] = sheetmetadataid
        instanceId = url.pop()
        metadataId = url.pop()
        metadata = applicationObj.getSheetMetadataById(metadataId)
        instance = self.getSession().get(instanceId, metadata)

        res = dispatchCommand(self.getSession(), 'invoke',metadata, params, instance)

        self.__commit__()
        response = self.returnResponse(self.getSession(), rootSheet, formName)

        self.response.out.write(response)

    def __resolve_activity_basequery__(self, metadata, activityDef, secondaryUser):
        from orangescape.model.engine.execution.ProcessUtil import getProcessCell_PrefixName
        baseQuery = list()
        prefix_name = getProcessCell_PrefixName(activityDef)
        prefix_tenant = ''
        if activityDef.getActivityTenant() or activityDef.containsActivityTenantFormula():
            prefix_tenant = prefix_name
        if activityDef.getAssignedFor()=='AppRole' and metadata.getStartActivity().getSheetId() != activityDef.getSheetId():
            roleName = activityDef.getAssignedTo()
            subscriptionMetadata = self.getSession().getApplication().getSheetMetadata('RoleSubscription')
            refCellName = 'PrimaryUser'
            if secondaryUser:
                refCellName = 'SecondaryUser'
            refCell = subscriptionMetadata.getPublicCellMetadata(refCellName)
            if [roleSubscription for roleSubscription in self.getSession().getList(self.getSession().getUser(), refCell) if roleSubscription.getValue('AssignedName') == roleName]:
                baseQuery.append(( metadata.getPublicCellMetadata(prefix_name+'Status').getSheetId(),'=', activityDef.getSheetId()))
                baseQuery.append(( metadata.getPublicCellMetadata(prefix_tenant+'Tenant').getSheetId(),'=', self.getSession().getUser().getValue('Company')))
                return baseQuery
            return None
        else:
            baseQuery.append(( metadata.getPublicCellMetadata(prefix_name+'Status').getSheetId(),'=', activityDef.getSheetId()))
            baseQuery.append(( metadata.getPublicCellMetadata(prefix_name+'AssignedTo').getSheetId(),'=', self.getSession().getUser().getValue('UserId').split('@')[0]))
            baseQuery.append(( metadata.getPublicCellMetadata(prefix_tenant+'Tenant').getSheetId(),'=', self.getSession().getUser().getValue('Company')))
            return baseQuery

    def performReadForInbox(self, urlParamList,query_string, pageNumber, pageCount, secondaryUser=None):
        versionId=urlParamList.pop(0)
        metadataType=urlParamList.pop(0)
        sheetmetadataid=urlParamList.pop(0)
        activityDefObjId=urlParamList.pop(0)

        applicationObj=self.getSession().getApplication()
        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        activityDef=sheetmetadata.getActivityDefinitionById(activityDefObjId)
        searchDefList=activityDef.getSearchDefinitionList()
        searchDef=searchDefList.pop()
        params=self.getQueryStringParams(query_string)
        formName = self.getInboxFormName(params, activityDef, sheetmetadata)

        if self.getMimeType()==HTML_RESPONSE:
            return self.returnSearchResponse(sheetmetadata, searchDef, formName, pageNumber, pageCount, INBOX)
        else:
            totalCount = None
            baseQuery = self.__resolve_activity_basequery__(sheetmetadata, activityDef, secondaryUser)
            if baseQuery is not None:
                searchExe=SearchExecution(self.getSession())
                params = self.getQueryStringParams(query_string)
                searchResult = searchExe.execteSearch(sheetmetadata, self.getSession().getUser().getSheetMetadata(), self.getSession().getUser(), baseQuery, searchDef, pageNumber, pageCount, True, params)
                totalCount = searchExe.getTotalCount()
            else:
                searchResult = []
            return self.returnSearchResponse(sheetmetadata, searchDef, formName, pageNumber, pageCount, INBOX, searchResult, True, totalCount)

    def readforSearch(self,metadatatype,applicationid,parentsheetmetadataid,taskid,sheetmetadataid,instanceId,cellName,url=None,pageNumber=None,pageCount=None):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        jsonStr=  self.performReadforSearch(urlParamList,query_string, pageNumber, pageCount)
        self.response.out.write(jsonStr)

    def performReadforSearch(self,urlParamList,query_string, pageNumber, pageCount):
        #to match the existing url pop
        if pageCount is not None:
            urlParamList.pop()
        if pageNumber is not None:
            urlParamList.pop()

        versionId=urlParamList.pop(0)
        metadataType=urlParamList.pop(0)
        parentSheetMetadataId=urlParamList.pop(0)
        activityDefid=urlParamList.pop(0)

        urlParamList.pop()
        cellName=urlParamList.pop()
        instanceid=urlParamList.pop()
        sheetMetadataId=urlParamList.pop()
        sheetmetadata = self.getSession().getApplication().getSheetMetadataById(sheetMetadataId)

        cellObj=sheetmetadata.getPublicCellMetadata(cellName)
        searchDef =cellObj.getSearchDefinitionList()[0]
        sheetObj=self.getSession().get(instanceid,sheetmetadata)
        lhsSheetMetadata = cellObj.getReferredSheetMetadata()

        params = self.getQueryStringParams(query_string)
        formName = self.getSearchFormName(params, searchDef, lhsSheetMetadata)

        if self.getMimeType()==HTML_RESPONSE:
            return self.returnSearchResponse(lhsSheetMetadata, searchDef, formName, pageNumber, pageCount, SEARCH)
        else:
            baseQuery=list()
            serializeChildRecord = False
            #need to revisit for advance search,as of now for ordinary search formName is removed from url
            if query_string.__contains__('form='):
                serializeChildRecord = True
            searchExe=SearchExecution(self.getSession())
            searchResult = searchExe.execteSearch(lhsSheetMetadata, sheetObj.getSheetMetadata(), sheetObj, baseQuery, searchDef, pageNumber, pageCount, serializeChildRecord, params)
            return self.returnSearchResponse(lhsSheetMetadata, searchDef, formName, pageNumber, pageCount, SEARCH, searchResult, serializeChildRecord)

    def updateUser(self,metadatatype,applicationid,sheetmetadataid,activitydefinitionid,pageNumber=None,pageCount=None, SecondaryUser=None):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        params = self.getQueryStringParams(query_string)
        user = self.getSession().getUser()
        dispatchCommand(self.getSession(), 'update', user, params)
        self.__commit__()
        jsonStr = self.performReadForInbox(urlParamList,query_string,pageNumber,pageCount,SecondaryUser)
        self.response.out.write(jsonStr)

    def searchUser(self,metadatatype,applicationid,sheetmetadataid,activitydefinitionid,cellName,pageNumber=None,pageCount=None, SecondaryUser=None):
        urlParamList=getUrlParams(self.request.path)
        if SecondaryUser:
            urlParamList.pop(4)
        query_string=self.request.query_string
        user = self.getSession().getUser()
        actDefId = user.getValue('Status')
        userSheetMetadataId = user.getSheetMetadata().getSheetId()
        urlParamList[2] = urlParamList[4] = userSheetMetadataId
        urlParamList[3] = actDefId
        urlParamList[5] = user.getSheetId()
        jsonStr = self.performReadforSearch(urlParamList,query_string, None, None)
        self.response.out.write(jsonStr)

    def deleteforInbox(self,metadatatype,applicationid,sheetmetadataid,activitydefinitionid,pageNumber=None,pageCount=None, url=None, SecondaryUser=None):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        instanceId = urlParamList.pop()
        metadataId = urlParamList.pop()
        refcell = urlParamList.pop()
        metadata = self.getSession().getApplication().getSheetMetadataById(metadataId)
        instance = self.getSession().get(instanceId, metadata)
        dispatchCommand(self.getSession(), 'delete', instance)
        self.__commit__()
        jsonStr = self.performReadForInbox(urlParamList,query_string,pageNumber,pageCount,SecondaryUser)
        self.response.out.write(jsonStr)

    def invokeforInbox(self,metadatatype,applicationid,sheetmetadataid,activitydefinitionid,pageNumber=None,pageCount=None, url=None, SecondaryUser=None):
        urlParamList=getUrlParams(self.request.path)
        if SecondaryUser:
            urlParamList.pop(4)
        inboxUrlList = urlParamList[0:6]
        query_string=self.request.query_string
        values = self.request.params
        user = self.getSession().getUser()
        userSheetMetadataId = user.getSheetMetadata().getSheetId()
        actDefId = user.getValue('Status')
        urlParamList[2] = urlParamList[4] = userSheetMetadataId
        urlParamList[3] = actDefId
        urlParamList[5] = user.getSheetId()

        instanceId = urlParamList.pop()
        metadataId = urlParamList.pop()
        metadata = self.getSession().getApplication().getSheetMetadataById(metadataId)
        instance = self.getSession().get(instanceId, metadata)

        params = {}
        for key, value in values.iteritems():
            params[key] = value

        rootSheetMetadataId = inboxUrlList[2]
        modifiedIn = inboxUrlList[3]
        self.getSession().setModifiedIn(modifiedIn)
        applicationObj=self.getSession().getApplication()
        rootSheetMetadata = applicationObj.getSheetMetadataById(rootSheetMetadataId)
        actDef=rootSheetMetadata.getActivityDefinitionById(modifiedIn)
        params['form'] = self.getInboxFormName(params, actDef, rootSheetMetadata)
        params['rootSheetMetadataId'] = rootSheetMetadataId

        dispatchCommand(self.getSession(), 'invoke',metadata, params, instance)
        self.__commit__()

        jsonStr = self.performReadForInbox(inboxUrlList,query_string,pageNumber,pageCount,SecondaryUser)
        self.response.out.write(jsonStr)

    def keysByActivity(self, metadatatype, applicationid, sheetmetadataid, activitydefinitionid, secondaryuser=None):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)
        applicationObj=self.getSession().getApplication()
        if secondaryuser:
            urlParamList.pop()
        urlParamList.pop()
        activityDefObjId=urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        activityDef=sheetmetadata.getActivityDefinitionById(activityDefObjId)
        searchDefList=activityDef.getSearchDefinitionList()
        jsonStr = '[]'
        baseQuery = self.__resolve_activity_basequery__(sheetmetadata, activityDef, secondaryuser)
        if baseQuery:
            searchDef=searchDefList.pop()
            searchExec = SearchExecution(self.getSession())
            params = self.getQueryStringParams(self.request.query_string)
            jsonStr = searchExec.query_keys(sheetmetadata, self.getSession().getUser(), searchDef, baseQuery, values.get('ModifiedAt'), params)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def queryByActivity(self, metadatatype, applicationid, sheetmetadataid, activitydefinitionid, secondaryuser=None):
        from orangescape.model.server.util.ReportSerializer import includeSysCells
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)
        applicationObj=self.getSession().getApplication()
        if secondaryuser:
            urlParamList.pop()
        urlParamList.pop()
        activityDefObjId=urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        activityDef=sheetmetadata.getActivityDefinitionById(activityDefObjId)
        jsonStr = '{}'
        searchDefList=activityDef.getSearchDefinitionList()
        baseQuery = self.__resolve_activity_basequery__(sheetmetadata, activityDef, secondaryuser)
        if baseQuery:
            searchDef=searchDefList.pop()
            searchExec = SearchExecution(self.getSession())
            columns = eval(values.get('columns')) if values.get('columns') else [cell.getCellName() for cell in sheetmetadata.getCellMetadataList() if cell.getRowNumber()>0 or cell.getCellName() in includeSysCells]
            params = self.getQueryStringParams(self.request.query_string)
            jsonStr = searchExec.query_entities(sheetmetadata, self.getSession().getUser(), searchDef, baseQuery, columns, values.get('ModifiedAt'), params)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def getbykeysByActivity(self, metadatatype, applicationid, sheetmetadataid, activitydefinitionid, SecondaryUser=None):
        from orangescape.model.server.util.ReportSerializer import ReportSyncSerializer, includeSysCells
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)
        keys = values.get('keys')
        keys = eval(keys) if keys else []
        applicationObj=self.getSession().getApplication()
        if SecondaryUser:
            urlParamList.pop()
        urlParamList.pop()
        activityDefObjId=urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        activityDef=sheetmetadata.getActivityDefinitionById(activityDefObjId)

        searchExec = SearchExecution(self.getSession())
        entities = self.getSession().get_by_keys(sheetmetadata, keys)
        columns = eval(values.get('columns')) if values.get('columns') else [cell.getCellName() for cell in sheetmetadata.getCellMetadataList() if cell.getRowNumber()>0 or cell.getCellName() in includeSysCells]
        jsonStr = ReportSyncSerializer(self.getSession()).serializeWithKeys(sheetmetadata, entities, columns)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def aggregateEntitiesByActivity(self, metadatatype, applicationid, sheetmetadataid, activitydefinitionid, secondaryuser=None):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)

        missedParams = [itm for itm in ('measures', 'dimensions', 'operations') if not values.has_key(itm)]
        if missedParams:
            raise ReportEngineError, Report1001%(' and '.join(missedParams))

        applicationObj=self.getSession().getApplication()
        if secondaryuser:
            urlParamList.pop()
        urlParamList.pop()
        activityDefObjId=urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        activityDef=sheetmetadata.getActivityDefinitionById(activityDefObjId)
        jsonStr = '{}'
        searchDefList=activityDef.getSearchDefinitionList()
        baseQuery = self.__resolve_activity_basequery__(sheetmetadata, activityDef, secondaryuser)
        if baseQuery:
            from orangescape.model.server.util.ReportSerializer import serializeAggregatedData
            searchDef=searchDefList.pop()
            measures = eval(values.get('measures'))
            dimensions = eval(values.get('dimensions'))
            operations = eval(values.get('operations'))
            params = self.getQueryStringParams(self.request.query_string)
            jsonStr = serializeAggregatedData(SearchExecution(self.getSession()).aggregate_entities(sheetmetadata, self.getSession().getUser(), searchDef, baseQuery, measures, dimensions, operations, params))
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def keys(self, metadatatype, applicationid, parentsheetmetadataid, taskid, sheetmetadataid, instanceId, cellName, url=None):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string

        values=self.getQueryStringParams(query_string)
        url_path="/"+"/".join(str(segment) for segment in urlParamList)
        #to match the existing url pop

        versionId=urlParamList.pop(0)
        metadataType=urlParamList.pop(0)
        parentSheetMetadataId=urlParamList.pop(0)
        activityDefid=urlParamList.pop(0)

        urlParamList.pop()
        cellName=urlParamList.pop()
        instanceid=urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = self.getSession().getApplication().getSheetMetadataById(sheetmetadataid)
        cellObj=sheetmetadata.getPublicCellMetadata(cellName)
        searchDefList =cellObj.getSearchDefinitionList()
        if len(searchDefList) > 0:
            instance = self.getSession().get(instanceid, sheetmetadata)
            baseQuery = list()
            searchDef=searchDefList[0]
            searchSheetMetadata=searchDef.getCellMetadata().getReferredSheetMetadata()
            searchExec = SearchExecution(self.getSession())
            params = self.getQueryStringParams(self.request.query_string)
            jsonStr = searchExec.query_keys(searchSheetMetadata, instance, searchDef, baseQuery, values.get('ModifiedAt'), params)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def query(self, metadatatype, applicationid, parentsheetmetadataid, taskid, sheetmetadataid, instanceId, cellName, url=None):
        from orangescape.model.server.util.ReportSerializer import includeSysCells
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string

        values=self.getQueryStringParams(query_string)
        url_path="/"+"/".join(str(segment) for segment in urlParamList)
        #to match the existing url pop

        versionId=urlParamList.pop(0)
        metadataType=urlParamList.pop(0)
        parentSheetMetadataId=urlParamList.pop(0)
        activityDefid=urlParamList.pop(0)

        urlParamList.pop()
        cellName=urlParamList.pop()
        instanceid=urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = self.getSession().getApplication().getSheetMetadataById(sheetmetadataid)
        cellObj=sheetmetadata.getPublicCellMetadata(cellName)
        searchDefList =cellObj.getSearchDefinitionList()
        instance=self.getSession().get(instanceid, sheetmetadata)

        jsonStr = '[]'
        if len(searchDefList) > 0:
            baseQuery = list()
            searchDef=searchDefList[0]
            searchSheetMetadata=searchDef.getCellMetadata().getReferredSheetMetadata()
            columns = eval(values.get('columns')) if values.get('columns') else [cell.getCellName() for cell in searchSheetMetadata.getCellMetadataList() if cell.getRowNumber()>0 or cell.getCellName() in includeSysCells]
            searchExec = SearchExecution(self.getSession())
            params = self.getQueryStringParams(self.request.query_string)
            jsonStr = searchExec.query_entities(searchSheetMetadata, instance, searchDef, baseQuery, columns, values.get('ModifiedAt'), params)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def getbykeys(self, metadatatype, applicationid, parentsheetmetadataid, taskid, sheetmetadataid, instanceId, cellName, url=None):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        keys = self.request.get('keys')
        keys = eval(keys) if keys else []

        values=self.getQueryStringParams(query_string)
        url_path="/"+"/".join(str(segment) for segment in urlParamList)
        #to match the existing url pop

        versionId=urlParamList.pop(0)
        metadataType=urlParamList.pop(0)
        parentSheetMetadataId=urlParamList.pop(0)
        activityDefid=urlParamList.pop(0)

        urlParamList.pop()
        cellName=urlParamList.pop()
        instanceid=urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = self.getSession().getApplication().getSheetMetadataById(sheetmetadataid)
        cellObj=sheetmetadata.getPublicCellMetadata(cellName)
        searchDefList =cellObj.getSearchDefinitionList()
        sheetObj=self.getSession().get(instanceid, sheetmetadata)

        jsonStr = '{}'
        if len(searchDefList) > 0:
            from orangescape.model.server.util.ReportSerializer import ReportSyncSerializer, includeSysCells
            searchDef=searchDefList[0]
            searchSheetMetadata=searchDef.getCellMetadata().getReferredSheetMetadata()
            entities = self.getSession().get_by_keys(searchSheetMetadata, keys)
            columns = eval(values.get('columns')) if values.get('columns') else [cell.getCellName() for cell in searchSheetMetadata.getCellMetadataList() if cell.getRowNumber()>0 or cell.getCellName() in includeSysCells]
            jsonStr = ReportSyncSerializer(self.getSession()).serializeWithKeys(searchSheetMetadata, entities, columns)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def aggregate(self, metadatatype, applicationid, parentsheetmetadataid, taskid, sheetmetadataid, instanceId, cellName, url=None):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string

        values=self.getQueryStringParams(query_string)
        url_path="/"+"/".join(str(segment) for segment in urlParamList)
        #to match the existing url pop

        missedParams = [itm for itm in ('measures', 'dimensions', 'operations') if not values.has_key(itm)]
        if missedParams:
            raise ReportEngineError, Report1001%(' and '.join(missedParams))

        versionId=urlParamList.pop(0)
        metadataType=urlParamList.pop(0)
        parentSheetMetadataId=urlParamList.pop(0)
        activityDefid=urlParamList.pop(0)

        urlParamList.pop()
        cellName=urlParamList.pop()
        instanceid=urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = self.getSession().getApplication().getSheetMetadataById(sheetmetadataid)
        cellObj=sheetmetadata.getPublicCellMetadata(cellName)
        searchDefList =cellObj.getSearchDefinitionList()
        jsonStr = '[]'
        if len(searchDefList) > 0:
            from orangescape.model.server.util.ReportSerializer import serializeAggregatedData
            instance = self.getSession().get(instanceid, sheetmetadata)
            baseQuery = list()
            searchDef=searchDefList[0]
            searchSheetMetadata=searchDef.getCellMetadata().getReferredSheetMetadata()

            measures = eval(values.get('measures'))
            dimensions = eval(values.get('dimensions'))
            operations = eval(values.get('operations'))
            params = self.getQueryStringParams(self.request.query_string)
            jsonStr = serializeAggregatedData(SearchExecution(self.getSession()).aggregate_entities(searchSheetMetadata, instance, searchDef, baseQuery, measures, dimensions, operations, params))

        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def keysBySearch(self, metadatatype, applicationid, sheetmetadataid, searchdefinitionid):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)
        applicationObj=self.getSession().getApplication()
        #pop the /keys word
        urlParamList.pop()
        searchDefObjId=urlParamList.pop()
        #pop the /report word
        urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        searchDef=sheetmetadata.getSearchDefinitionById(searchDefObjId)
        jsonStr = '[]'
        searchExec = SearchExecution(self.getSession())
        rhsSheet = self.getSession().getUser()
        baseQuery = list()
        params = self.getQueryStringParams(self.request.query_string)
        jsonStr = searchExec.query_keys(sheetmetadata, rhsSheet, searchDef, baseQuery, values.get('ModifiedAt'), params)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def queryBySearch(self, metadatatype, applicationid, sheetmetadataid, searchdefinitionid):
        from orangescape.model.server.util.ReportSerializer import includeSysCells
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)
        applicationObj=self.getSession().getApplication()
        urlParamList.pop()
        searchDefObjId=urlParamList.pop()
        #pop the /report word
        urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        searchDef=sheetmetadata.getSearchDefinitionById(searchDefObjId)
        jsonStr = '[]'
        searchExec = SearchExecution(self.getSession())
        rhsSheet = self.getSession().getUser()
        baseQuery = list()
        columns = eval(values.get('columns')) if values.get('columns') else [cell.getCellName() for cell in sheetmetadata.getCellMetadataList() if cell.getRowNumber()>0 or cell.getCellName() in includeSysCells]
        params = self.getQueryStringParams(self.request.query_string)
        jsonStr = searchExec.query_entities(sheetmetadata, rhsSheet, searchDef, baseQuery, columns, values.get('ModifiedAt'), params)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def getbykeysBySearch(self, metadatatype, applicationid, sheetmetadataid, searchdefinitionid):
        from orangescape.model.server.util.ReportSerializer import ReportSyncSerializer, includeSysCells
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)
        keys = values.get('keys')
        keys = eval(keys) if keys else []
        applicationObj=self.getSession().getApplication()
        urlParamList.pop()
        searchDefObjId=urlParamList.pop()
        #pop the /report word
        urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        searchDef=sheetmetadata.getSearchDefinitionById(searchDefObjId)

        entities = self.getSession().get_by_keys(sheetmetadata, keys)
        columns = eval(values.get('columns')) if values.get('columns') else [cell.getCellName() for cell in sheetmetadata.getCellMetadataList() if cell.getRowNumber()>0 or cell.getCellName() in includeSysCells]
        jsonStr = ReportSyncSerializer(self.getSession()).serializeWithKeys(sheetmetadata, entities, columns)
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def aggregateEntitiesBySearch(self, metadatatype, applicationid, sheetmetadataid, searchdefinitionid):
        from orangescape.model.server.util.ReportSerializer import serializeAggregatedData
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)

        missedParams = [itm for itm in ('measures', 'dimensions', 'operations') if not values.has_key(itm)]
        if missedParams:
            raise ReportEngineError, Report1001%(' and '.join(missedParams))

        applicationObj=self.getSession().getApplication()
        urlParamList.pop()
        searchDefObjId=urlParamList.pop()
        urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
        searchDef=sheetmetadata.getSearchDefinitionById(searchDefObjId)
#        try:
        measures = eval(values.get('measures'))
        dimensions = eval(values.get('dimensions'))
        operations = eval(values.get('operations'))
#        except SyntaxError, e:
#            raise ReportEngineError, Report1002%()

        rhsSheet = self.getSession().getUser()
        baseQuery = list()
        params = self.getQueryStringParams(self.request.query_string)
        jsonStr = serializeAggregatedData(SearchExecution(self.getSession()).aggregate_entities(sheetmetadata, rhsSheet, searchDef, baseQuery, measures, dimensions, operations, params))
        self.response.out.write(self.getJsonForJsonp(jsonStr))

    def getMetaInfo(self, metadatatype, applicationid, sheetmetadataid, searchdefinitionid):
        urlParamList=getUrlParams(self.request.path)
        query_string=self.request.query_string
        values=self.getQueryStringParams(query_string)

        applicationObj=self.getSession().getApplication()
        urlParamList.pop()
        path=''
        for i in urlParamList:
            path = path+i+'/'
        searchDefObjId=urlParamList.pop()
        urlParamList.pop()
        sheetmetadataid=urlParamList.pop()

        if self.getMimeType()==HTML_RESPONSE:
            url_path = self.request.path
            self.response.out.write(renderTemplate("report.preference.html", dict(), self))
        else:
            from orangescape.model.server.util.ReportSerializer import serializeMetaInfoWithFilter
            sheetmetadata = applicationObj.getSheetMetadataById(sheetmetadataid)
            searchDef = sheetmetadata.getSearchDefinitionById(searchdefinitionid)
            jsonStr = '{'+serializeMetaInfoWithFilter(sheetmetadata,searchDef,path)+'}'
            self.response.out.write(self.getJsonForJsonp(jsonStr))

    def metadataSync(self, metadatatype=None, applicationid=None):
        from orangescape.model.server.util.MetadataSync import MetadataSync, moveApproleToNextState
        from orangescape.model.engine.Component import Component
        component = Component(self.getSession())

        params = self.getQueryStringParams(self.request.query_string)
        userid = params.get('userid')

        userMetadata = self.getSession().getApplication().getSheetMetadata('User')
        userIns = self.getSession().getIfExists(userid, userMetadata)
        if userIns:
            self.getSession().setUser(userIns)
            globalInst = self.getSession().getIfExists('global', self.getSession().getApplication().getSheetMetadata('Global'))
            if globalInst:
                newSheetDict = MetadataSync(component, globalInst).createObjects(globalInst)

                appRoleMetadata = self.getSession().getApplication().getSheetMetadata('AppRole')
                if newSheetDict.has_key(appRoleMetadata.getSheetId()):
                    companyInst = self.getSession().get(userIns.getValue('Company'), self.getSession().getApplication().getSheetMetadata('Company'))
                    newApproleDict = newSheetDict[appRoleMetadata.getSheetId()]
                    for appRoleInst in newApproleDict.itervalues():
                        moveApproleToNextState(component, appRoleInst, companyInst)
            else:
                resp = "Couldn't find the Global instance to do metadata sync"
                logging.error(resp)
                self.response.out.write(self.getJsonForJsonp(resp))
        else:
            resp = "Couldn't find the user %s to do metadata sync"%(userid)
            logging.error(resp)
            self.response.out.write(self.getJsonForJsonp(resp))

        self.__commit__()
#********************************************************************************************************************************************