import logging

class JstlGenerator:
    def __init__(self,session):
        self.JSTL = ""
        self.macroTable = dict()
        self.actionMappingTable = dict()
        self.formSerializeTable = dict()
        self.importMappingTable = dict()
        self.isQueryGridView = False
        self.session = session
        self.SheetMetadata = self.session.getApplication().getSheetMetadata('SheetMetadata')
        self.GridView = self.session.getApplication().getSheetMetadata('GridView')
        self.GridRow = self.session.getApplication().getSheetMetadata('GridRow')
        self.GridColumn = self.session.getApplication().getSheetMetadata('GridColumn')
        self.GridCell = self.session.getApplication().getSheetMetadata('GridCell')
        self.RowMetadata = self.session.getApplication().getSheetMetadata('RowMetadata')
        self.CellMetadata = self.session.getApplication().getSheetMetadata('CellMetadata')
        self.Formula = self.session.getApplication().getSheetMetadata('Formula')
        self.ActivityPermission = self.session.getApplication().getSheetMetadata('ActivityPermission')
        self.Criteria = self.session.getApplication().getSheetMetadata('Criteria')
        self.Condition = self.session.getApplication().getSheetMetadata('Condition')
        self.Section = self.session.getApplication().getSheetMetadata('Section')
        self.Branch = self.session.getApplication().getSheetMetadata('Branch')
        self.Node = self.session.getApplication().getSheetMetadata('Node')
        self.Property = self.session.getApplication().getSheetMetadata('Property')
        self.Range = self.session.getApplication().getSheetMetadata('Range')
        self.RangeValue = self.session.getApplication().getSheetMetadata('RangeValue')
        self.ValidationGrid = self.session.getApplication().getSheetMetadata('ValidationGrid')
        self.ExcludeValidationGrid = self.session.getApplication().getSheetMetadata('ExcludeValidationGrid')
        self.IncludeValidationGrid = self.session.getApplication().getSheetMetadata('IncludeValidationGrid')
        self.Validation = self.session.getApplication().getSheetMetadata('Validation')
        self.ActivityDefinition = self.session.getApplication().getSheetMetadata('ActivityDefinition')
        self.SearchDefinition = self.session.getApplication().getSheetMetadata('SearchDefinition')
        self.Style = self.session.getApplication().getSheetMetadata('Style')

    def build(self, gv):
        self.rootGrid = gv
        strBuffer = list()
        if gv.getValue("QSheetMetadata") is not None:
            self.isQueryGridView = True
        rootTable = {'ManyToOne':{},'OneToMany':{}}
        self.getJstlTable(gv, rootTable);
        for tab in self.macroTable:
            strBuffer.append(self.macroTable[tab])
        strBuffer.append("\n${" + self.getMacroName(gv) + "(getRoot(), 2, '')}")

        self.JSTL = ''.join(strBuffer)
        #formmapping creation
        self.formSerializeTable['root'] = rootTable

    def getMacroName(self, gv):
        sheetmeta = self.session.get(gv.getValue('SheetMetadata'),self.SheetMetadata)
        return sheetmeta.getSheetName() + "_" + gv.getSheetId()

    def getJstlTable(self, gv, rootTable):
        strBuffer = list()
        if not self.macroTable.__contains__(gv.getSheetId()):
            sheetmeta = self.session.get(gv.getValue('SheetMetadata'),self.SheetMetadata)
            strBuffer.append("{macro "+self.getMacroName( gv)+"(inst, permit, refUrl)}\n")
            gridRow_gridView_refCell = self.GridRow.getPublicCellMetadata('GridView')
            gridRowList = self.session.getList(gv,gridRow_gridView_refCell)
            gridRowList.sort(lambda x, y: cmp(x.getValue('RowNumber'), y.getValue('RowNumber')))
            strBuffer.append("<table id='"+gv.getSheetId()+"' border=0 cellpadding=0 cellspacing=0 style='border-collapse:collapse;'")
            if self.rootGrid.getValue('Property') == 'AutoWidth':
                strBuffer.append(" width=100% ")
            strBuffer.append(">\n")
            for grow in gridRowList:
                strBuffer.append("{var instance = inst}\n")
                if grow.getValue('CellMetadata'):
                    #has reference cell
                    refcell = self.session.get(grow.getValue('CellMetadata'),self.CellMetadata)
                    refcellsheetmeta = self.session.get(refcell.getValue('SheetMetadata'),self.SheetMetadata)
                    refcellrefsheetmeta = self.session.get(refcell.getValue('ReferredSheetMetadata'),self.SheetMetadata)
                    if(refcellsheetmeta.getSheetId() == sheetmeta.getSheetId() and refcellrefsheetmeta.getSheetId() != refcellsheetmeta.getSheetId()):
                        #many-to-one reference cell
                        manyToOneTable = rootTable['ManyToOne']
                        if manyToOneTable.get(refcell.getValue('CellName')) is None:
                            manyToOneTable[refcell.getValue('CellName')] = {'ManyToOne':{},'OneToMany':{}}
                        strBuffer.append("{var instance = inst.get('"+refcell.getValue('CellName')+"')}\n")
                        strBuffer.append("{if instance}\n")
                        strBuffer.append("{var relationUrl = refUrl+\"/"+refcell.getSheetId()+"/"+refcellrefsheetmeta.getSheetId()+"/\"+instance.getValue('SheetId')}\n")
                        strBuffer.append(self.getJstlRow(gv, grow, manyToOneTable[refcell.getValue('CellName')]))
                        strBuffer.append("{/if}\n")
                    else:
                        #one-to-many reference cell
                        oneToManyTable = rootTable['OneToMany']
                        if oneToManyTable.get(refcell.getValue('CellName')+"."+refcellsheetmeta.getSheetName()) is None:
                            oneToManyTable[refcell.getValue('CellName')+"."+refcellsheetmeta.getSheetName()] = {'ManyToOne':{},'OneToMany':{}}
                        childListStr = ""
                        oneTomanyCellName = refcell.getValue('CellName')+"."+refcellsheetmeta.getSheetName()
                        if not self.isQueryGridView:
                            orderByCellName = 'CreatedAt'
                            if grow.getValue('OrderByCell'):
                                orderByCell = self.session.get(grow.getValue('OrderByCell'),self.CellMetadata)
                                orderByCellName = orderByCell.getValue('CellName')
                            isDesc = "false"
                            if grow.getValue('IsDescending'):
                                isDesc = "true"
                            childListStr = "getOneToManySheetList(inst,'"+oneTomanyCellName+"','"+orderByCellName+"',"+isDesc+")"
                        else:
                            childListStr = "inst.getList('"+oneTomanyCellName+"')"
                        strBuffer.append("{for instance in "+childListStr+"}\n")
                        strBuffer.append("{var relationUrl = refUrl+\"/"+refcell.getSheetId()+"/"+refcellsheetmeta.getSheetId()+"/\"+instance.getValue('SheetId')}\n")
                        strBuffer.append(self.getJstlRow(gv, grow, oneToManyTable[refcell.getValue('CellName')+"."+refcellsheetmeta.getSheetName()]))
                        strBuffer.append("{/for}")
                else:
                    strBuffer.append("{var relationUrl = refUrl}\n")
                    strBuffer.append(self.getJstlRow(gv, grow, rootTable))

            strBuffer.append("</table>\n")
            strBuffer.append("{/macro}\n")
            self.macroTable[gv.getSheetId()] = ''.join(strBuffer);

    def getJstlRow(self, gv, grow, serializeTable):
        strBuffer = list()
        if grow.getValue('Style'):
            strBuffer.append("{var rowStyle= 'class = "+self.getStyleName(grow.getValue('Style'))+"'}\n")
        elif grow.getValue('GlobalStyle'):
            strBuffer.append("{var rowStyle= 'class = "+grow.getValue('GlobalStyle')+"'}\n")
        else:
            strBuffer.append("{var rowStyle=null}\n")

        if grow.getValue('AlternateStyle') :
            strBuffer.append("{var alternateRowStyle= 'class = "+self.getStyleName(grow.getValue('AlternateStyle'))+"'}\n")
        elif grow.getValue('AlternateGlobalStyle') :
            strBuffer.append("{var alternateRowStyle= 'class = "+grow.getValue('AlternateGlobalStyle')+"'}\n")
        else:
            strBuffer.append("{var alternateRowStyle=null}\n")
        strBuffer.append("<tr id='"+grow.getSheetId()+"'")
        strBuffer.append("{if alternateRowStyle && (parseInt(instance_index)+1) % 2 ==0} ${alternateRowStyle} {else if rowStyle} ${rowStyle} {/if}")
        strBuffer.append(">\n")
        gridCell_gridRow_refCell = self.GridCell.getPublicCellMetadata('GridRow')
        gridCellList = self.session.getList(grow,gridCell_gridRow_refCell)
        gridCellList.sort(lambda x, y: cmp(x.getValue('ColumnNumber'), y.getValue('ColumnNumber')))
        for gcell in gridCellList:
            if(gcell.getValue('Hidden') != 1):
                strBuffer.append("{var permission = permit}\n")
                condPermJstl = self.getDefaultConditionPermissionJstl(gcell)
                if(gcell.getValue('PermissionType') is not None or len(condPermJstl) > 0):
                    strBuffer.append(self.getPermissionJstl(gcell.getValue('PermissionType'), condPermJstl))

                actPerm_gridCell_refCell = self.ActivityPermission.getPublicCellMetadata('GridCell')
                permissionList = self.session.getList(gcell, actPerm_gridCell_refCell);
                if(len(permissionList) > 0):
                    strBuffer.append("{if 'equal' == 'not equal'}\n")
                    for actperm in permissionList:
                        act = self.session.get(actperm.getValue('ActivityDefinition'),self.ActivityDefinition)
                        statusName = self.getActivityStatus(act)
                        condPermJstl = self.getActivityConditionPermissionJstl(actperm)
                        if(actperm.getValue('PermissionType') is not None or len(condPermJstl) > 0):
                            strBuffer.append("{elseif '"+act.getSheetId()+"' == activityDefinitionId}\n")
                            strBuffer.append(self.getPermissionJstl(actperm.getValue('PermissionType'), condPermJstl))
                    strBuffer.append("{/if}\n")

                strBuffer.append("<td ")
                strBuffer.append(self.getJstlAlign(gcell))
                if gcell.getValue('ColumnSpanned'):
                    strBuffer.append(" colspan="+str(int(gcell.getValue('ColumnSpanned'))))
                if gcell.getValue('RowSpanned'):
                    strBuffer.append(" rowspan="+str(int(gcell.getValue('RowSpanned'))))

                strBuffer.append("{if permission > 0.5}\n")
                if not self.hasGridView(gcell):
                    strBuffer.append(" height="+str(gcell.getValue('FinalHeight'))+"px")
                    strBuffer.append(" width="+str(gcell.getValue('FinalWidth'))+"px")
                    strBuffer.append(" style='min-width:"+str(gcell.getValue('FinalWidth'))+"px'")

                widgetType = ""
                if gcell.getValue('WidgetType'):
                    widgetType = gcell.getValue('WidgetType')
                strBuffer.append("{if permission == 1}\n")
                strBuffer.append(" class='readonly "+self.getReadOnlyStyle(gcell)+"'\n")
                strBuffer.append("{elseif 'label' == '"+widgetType+"'}\n")
                strBuffer.append(" class='label "+self.getJSTLClass(gcell)+"'\n")
                strBuffer.append("{else}\n")
                if(not gcell.getValue('CellMetadata') or gcell.getValue('Command') == 'create' or gcell.getValue('Command') == 'createupdate'):
                    strBuffer.append(" class='"+self.getJSTLClass(gcell)+"'")
                strBuffer.append("{/if}\n")
                strBuffer.append(">\n")
                strBuffer.append(self.getJstlCell(gv, gcell, serializeTable))
                strBuffer.append("{else}\n")
                strBuffer.append(">\n"),
                strBuffer.append("{/if}\n")
                strBuffer.append("</td>\n")
        strBuffer.append("</tr>\n")
        return ''.join(strBuffer)

    def getJstlCell(self, gv, gcell, serializeTable):
        strBuffer = list()
        if gcell.getValue('WidgetType') and gcell.getValue('CellMetadata'):
            cellmeta = self.session.get(gcell.getValue('CellMetadata'),self.CellMetadata)
            gridViewId = gv.getSheetId()
            if gcell.getValue('Command') == 'create' or gcell.getValue('Command') == 'createupdate':
                refcell = self.session.get(gcell.getValue('CellMetadata'),self.CellMetadata)
                refcellsheetmeta = self.session.get(refcell.getValue('SheetMetadata'),self.SheetMetadata)
                #via many to one refcell - creation of parent
                if(gcell.getValue('Command') == 'createupdate'):
                    refcellsheetmeta = self.session.get(refcell.getValue('ReferredSheetMetadata'),self.SheetMetadata)
                strBuffer.append("{var refCreateUrl = relationUrl+\"/"+refcell.getSheetId()+"/"+refcellsheetmeta.getSheetId()+"\"}\n")
                strBuffer.append("${renderCRUD('"+gcell.getSheetId()+"','create', permission, '"+self.getPropertyValue(gcell,'src')+"',refCreateUrl)}\n")
            elif gcell.getValue('Command') == 'import':
                refcell = self.session.get(gcell.getValue('CellMetadata'),self.CellMetadata)
                refcellsheetmeta = self.session.get(refcell.getValue('SheetMetadata'),self.SheetMetadata)
                strBuffer.append("{var refImportUrl = relationUrl+\"/"+refcell.getSheetId()+"/"+refcellsheetmeta.getSheetId()+"\"}\n")
                strBuffer.append("${renderImport('"+gcell.getSheetId()+"','"+self.getPropertyValue(gcell,'src')+"',refImportUrl)}\n")
                self.importMappingTable[gcell.getSheetId()] = self.getImportPropertyDict(gcell)
            elif(gcell.getValue('WidgetType') == 'button' or gcell.getValue('WidgetType') == 'image' or gcell.getValue('WidgetType') == 'checkboxparamcopy'):
                cellMetadataName=''
                rhsCellMetadata = self.getPropertyValue(gcell,'Value','RHSCellMetadata')
                if rhsCellMetadata and len(rhsCellMetadata) > 0:
                    cellMetadataName=self.session.get(rhsCellMetadata,self.CellMetadata).getValue('CellName')

                strBuffer.append("${renderCellUpdate(instance, '" + cellmeta.getValue('CellName') + "','"+ str(gcell.getValue('WidgetType'))+"', '"
                                 + self.getJSTLClass(gcell) + "', " + str(self.isSubmit(gcell, cellmeta)) + ", '"
                                 +self.getPropertyValue(gcell,'Caption')+ "', '"+self.getPropertyValue(gcell,'Value')+ "', '"+self.getPropertyValue(gcell,'src')+"','"
                                 +self.getPropertyValue(gcell,'Value','ParamType')+"','"+cellMetadataName+"', relationUrl)}\n")
            else:
                strBuffer.append("{var widget = (permission==1?'readonly':'"+ str(gcell.getValue('WidgetType'))+"')}\n")
                strBuffer.append("{var format = '"+self.getCellFormat(cellmeta)+"'}\n")
                strBuffer.append("{var rangeValue = "+self.getRangeValue(cellmeta)+"}\n")

                searchDefList = self.session.getList(cellmeta,self.SearchDefinition.getPublicCellMetadata("CellMetadata"))
                advanceSearchId = ""
                if len(searchDefList) > 0:
                    searchDef = searchDefList.pop()
                    if searchDef.getValue('GridView'):
                        advanceSearchId = searchDef.getValue('GridView')
                textlength = 0
                if cellmeta.getValue('TextLength'):
                    textlength=cellmeta.getValue('TextLength')
                halign=""
                if gcell.getValue('HAlign'):
                    halign=gcell.getValue('HAlign')
                strBuffer.append("${@renderWidget('"+gridViewId+"', instance, '" + cellmeta.getValue('CellName')+ "', widget, '" + self.getJSTLClass(gcell) + "', "
                                     + str(gcell.getValue('FinalHeight')) + ", " + str(gcell.getValue('FinalWidth')) + ", "+ str(self.isSubmit(gcell, cellmeta))
                                     + ", format, "+str(textlength)+",'"+ self.getValue(cellmeta,'RegExp') +"','"+halign+"',rangeValue, '"+advanceSearchId+"' ,relationUrl)@}\n")

                validationOnReadOnly = 0
                if gcell.getValue('ValidationOnReadOnly') == 1:
                    validationOnReadOnly = 1
                strBuffer.append("{if widget != 'readonly' || "+str(validationOnReadOnly)+" == 1}\n")
                validation_gridCell_refCell = self.Validation.getPublicCellMetadata('GridCell')
                validationList = self.session.getList(gcell, validation_gridCell_refCell)
                strBuffer.append(self.getValidationJstl(gcell, validationList, cellmeta.getValue('CellName'), gridViewId))
                strBuffer.append("{/if}\n")
        else:
            gridView_gridCell_refCell = self.GridView.getPublicCellMetadata('GridCell')
            nestedGridViewList = self.session.getList(gcell,gridView_gridCell_refCell)
            if(gcell.getValue('GridView')):
                publicGrid = self.session.get(gcell.getValue('GridView'),self.GridView)
                self.getJstlTable(publicGrid, serializeTable);
                strBuffer.append("\n${"+self.getMacroName(publicGrid)+"(instance, permission, relationUrl)}\n")
            elif len(nestedGridViewList) > 0:
                for nestedGrid in nestedGridViewList:
                    self.getJstlTable(nestedGrid, serializeTable);
                    strBuffer.append("\n${"+self.getMacroName(nestedGrid)+"(instance, permission, relationUrl)}\n")
            elif(gcell.getValue('Section')):
                section = self.session.get(gcell.getValue('Section'),self.Section)
                strBuffer.append(self.getJstlSection(section))
            elif(gcell.getValue('Branch')):
                caption = self.getPropertyValue(gcell,'Caption')
                branch = self.session.get(gcell.getValue('Branch'),self.Branch)
                strBuffer.append("{var validationGrids = '"+self.getValidationGridList(gcell)+"'}\n")
                strBuffer.append("{var workflowRenderList = "+self.getWorkflowRenderPropertyList(gcell)+"}\n")
                self.actionMappingTable[caption+"~"+gcell.getSheetId()] = branch.getSheetId()
                strBuffer.append("${@renderAction(instance, permission,'" + self.getJSTLClass(gcell) +"','" +gcell.getSheetId()+"','" + str(gcell.getValue('WidgetType'))+"','"+str(branch.getValue('ProcessType'))+"','"
                                +caption+"','"+self.getPropertyValue(gcell,'src')+"','"+self.getPropertyValue(gcell,'Status')+"','"+self.getPropertyValue(gcell,'Target')+"','"+self.getPropertyValue(gcell,'Target','ValueDescription')+"','"+self.getPropertyValue(gcell,'Validate')+"', workflowRenderList, validationGrids, relationUrl)@}\n")
            elif(gcell.getValue('GotoBranch')):
                gridViewId = gcell.getValue('GotoGridView') or ''
                strBuffer.append("${renderGotoLink('"+self.getPropertyValue(gcell,'src')+"', instance, 'Status','"+gridViewId+"')}\n")
            elif(gcell.getValue('Command') == 'delete'):
                strBuffer.append("${renderCRUD('"+gcell.getSheetId()+"','delete', permission,'"+self.getPropertyValue(gcell,'src')+"',relationUrl)}\n")
            elif(gcell.getValue('Command') == 'attachment'):
                strBuffer.append("${renderAttachment(instance, relationUrl)}\n")
            elif(gcell.getValue('Command') == 'reattach'):
                strBuffer.append("${renderReAttach(instance, relationUrl)}\n")
            elif(gcell.getValue('Command') == 'removeAttach'):
                strBuffer.append("${renderRemoveAttach(instance, relationUrl)}\n")
            elif gcell.getValue('CellValue'):
                strBuffer.append(gcell.getValue('CellValue'))
            else:
                strBuffer.append("")
        return ''.join(strBuffer)


    def getJstlSection(self,section):
        strBuffer = list()
        strBuffer.append("<table border=0 cellpadding=0 cellspacing=0>\n")
        shmd = self.session.get(section.getValue("SheetMetadata"),self.SheetMetadata)
        sheet_row_refCell = self.RowMetadata.getPublicCellMetadata('SheetMetadata')
        row_cell_refCell = self.CellMetadata.getPublicCellMetadata('RowMetadata')
        srows = self.session.getList(shmd, sheet_row_refCell)
        srows.sort(lambda x, y: cmp(x.getValue('RowNumber'), y.getValue('RowNumber')))
        sfrom = self.session.get(section.getValue("From"),self.CellMetadata)
        sto = self.session.get(section.getValue("To"),self.CellMetadata)
        for srow in srows:
            if(srow.getValue('RowNumber') >= sfrom.getValue('RowNumber') and srow.getValue('RowNumber') <= sto.getValue('RowNumber')):
                strBuffer.append("<tr>\n")
                scells = self.session.getList(srow, row_cell_refCell)
                scells.sort(lambda x, y: cmp(x.getValue('ColumnNumber'), y.getValue('ColumnNumber')))
                for scell in scells:
                    if(scell.getValue('ColumnNumber') >= sfrom.getValue('ColumnNumber') and scell.getValue('ColumnNumber') <= sto.getValue('ColumnNumber')):
                        strBuffer.append("<td")
                        if(scell.getValue('ColumnSpanned')):
                            strBuffer.append(" colspan="+str(int(scell.getValue('ColumnSpanned'))))
                        if(scell.getValue('RowSpanned')):
                            strBuffer.append(" rowspan="+str(int(scell.getValue('RowSpanned'))))

                        strBuffer.append(" height="+str(scell.getValue('FinalHeight'))+"px")
                        strBuffer.append(" width="+str(scell.getValue('FinalWidth'))+"px")
                        strBuffer.append(" style='min-width:"+str(scell.getValue('FinalWidth'))+"px'")

                        stylestr = ""
                        if scell.getValue("Style"):
                            stylestr = self.getStyleName(scell.getValue("Style"))
                        elif scell.getValue('GlobalStyle'):
                            stylestr =  scell.getValue('GlobalStyle')
                        widget = "";
                        if(scell.getValue('CellName')):
                            strBuffer.append(">\n")
                            formula_cell_refCell = self.Formula.getPublicCellMetadata('CellMetadata')
                            formulaList = self.session.getList(scell, formula_cell_refCell)
                            if(len(formulaList) > 0):
                                widget = "label";
                            elif(scell.getValue("ReferredSheetMetadata")):
                                widget = "combobox";
                            else:
                                widget = "textbox";

                            strBuffer.append("{var widget = (permission==1?'readonly':'"+widget+"')}\n")
                            strBuffer.append("{var format = '"+self.getCellFormat(scell)+"'}\n")
                            strBuffer.append("{var rangeValue = "+self.getRangeValue(scell)+"}")

                            searchDefList = self.session.getList(scell,self.SearchDefinition.getPublicCellMetadata("CellMetadata"))
                            advanceSearchId = ""
                            if len(searchDefList) > 0:
                                searchDef = searchDefList.pop()
                                if searchDef.getValue('GridView'):
                                    advanceSearchId = searchDef.getValue('GridView')
                            textlength = 0
                            if scell.getValue('TextLength'):
                                textlength=scell.getValue('TextLength')
                            halign=""
                            strBuffer.append("${@renderWidget('', instance, '" + scell.getValue('CellName') + "', widget , '" + stylestr + "', "
                                    + str(scell.getValue('FinalHeight')) + ", " + str(scell.getValue('FinalWidth')) + ", " + str(self.getCellNodeCount(scell))
                                    + ", format,"+ str(textlength)+",'"+ self.getValue(scell,'RegExp')+"','"+halign+"', rangeValue, '"+ advanceSearchId +"',relationUrl)@}\n")
                        else:
                            strBuffer.append(" class='"+stylestr+"'")
                            strBuffer.append(">\n")
                            if(scell.getValue('CellValue')):
                                cellValue = scell.getValue('CellValue')
                                if isinstance(cellValue,str) or isinstance(cellValue,unicode):
                                    strBuffer.append(cellValue)
                                else:
                                    strBuffer.append(str(cellValue))
                        strBuffer.append("</td>\n")
                strBuffer.append("</tr>\n")
        strBuffer.append("</table>\n")
        return ''.join(strBuffer)

    def getDefaultConditionPermissionJstl(self, gcell):
        strBuffer = list()
        crieria_gridCell_visible = self.Criteria.getPublicCellMetadata('GridCell_Visible')
        crieria_gridCell_read = self.Criteria.getPublicCellMetadata('GridCell_Read')
        crieria_gridCell_write = self.Criteria.getPublicCellMetadata('GridCell_Write')

        visibleCriteriaList = self.session.getList(gcell,crieria_gridCell_visible)
        readCriteriaList = self.session.getList(gcell,crieria_gridCell_read)
        writeCriteriaList = self.session.getList(gcell,crieria_gridCell_write)

        if(len(visibleCriteriaList) > 0):
            strBuffer.append(self.constructConditionBasedPermission(visibleCriteriaList[0], 0.5))
        if(len(readCriteriaList) > 0):
            strBuffer.append(self.constructConditionBasedPermission(readCriteriaList[0], 1))
        if(len(writeCriteriaList) > 0):
            strBuffer.append(self.constructConditionBasedPermission(writeCriteriaList[0], 2))
        return ''.join(strBuffer)

    def getActivityConditionPermissionJstl(self, actperm):
        strBuffer = list()
        crieria_actPerm_visible = self.Criteria.getPublicCellMetadata('ActivityPermission_Visible')
        crieria_actPerm_read = self.Criteria.getPublicCellMetadata('ActivityPermission_Read')
        crieria_actPerm_write = self.Criteria.getPublicCellMetadata('ActivityPermission_Write')

        visibleCriteriaList = self.session.getList(actperm,crieria_actPerm_visible)
        readCriteriaList = self.session.getList(actperm,crieria_actPerm_read)
        writeCriteriaList = self.session.getList(actperm,crieria_actPerm_write)

        if(len(visibleCriteriaList) > 0):
            strBuffer.append(self.constructConditionBasedPermission(visibleCriteriaList[0], 0.5))
        if(len(readCriteriaList) > 0):
            strBuffer.append(self.constructConditionBasedPermission(readCriteriaList[0], 1))
        if(len(writeCriteriaList) > 0):
            strBuffer.append(self.constructConditionBasedPermission(writeCriteriaList[0], 2))
        return ''.join(strBuffer)

    def constructConditionBasedPermission(self,criteria,permissionType):
        criteriaCondStr = self.constructCriteria(criteria)
        strBuffer = list()
        if(len(criteriaCondStr) > 0):
            strBuffer.append("{elseif ")
            strBuffer.append(criteriaCondStr)
            strBuffer.append("}\n")
            strBuffer.append("{var permission = "+str(permissionType)+"}\n")
        return ''.join(strBuffer)

    def constructCriteria(self,criteria):
        strBuffer = list()
        strBuffer.append(self.constructCondition(criteria))
        criteria_criteria_refCell = self.Criteria.getPublicCellMetadata('Criteria')
        criteriaList = self.session.getList(criteria,criteria_criteria_refCell)
        for childCriteria in criteriaList:
            if criteria.getValue('AndOper'):
                strBuffer.append("&&")
            else:
                strBuffer.append("||")
            strBuffer.append(" ( ")
            strBuffer.append(self.constructCriteria(childCriteria))
            strBuffer.append(" ) ")
        return ''.join(strBuffer)

    def constructCondition(self, criteria):
        strBuffer = list()
        cond_criteria_refCell = self.Condition.getPublicCellMetadata('Criteria')
        conditionList = self.session.getList(criteria,cond_criteria_refCell)
        n = len(conditionList)
        for condition in conditionList:
            cellType=None
            if(n != len(conditionList)):
                if criteria.getValue('AndOper'):
                    strBuffer.append(" &&")
                else:
                    strBuffer.append(" ||")
            n = n - 1
            if condition.getValue('LHSCellMetadata'):
                lhsCellMetadata = self.session.get(condition.getValue('LHSCellMetadata'),self.CellMetadata)
                strBuffer.append(" instance.getValue('"+ str(lhsCellMetadata.getValue('CellName'))+"') ")
                cellType=lhsCellMetadata.getValue('IsStr')
            else:
                strBuffer.append(" '' ")
            strBuffer.append(condition.getValue('Operator'))
            if condition.getValue('RHSParamType') == 'Cell':
                if condition.getValue('RHSCellMetadata'):
                    rhsCellMetadata = self.session.get(condition.getValue('RHSCellMetadata'),self.CellMetadata)
                    strBuffer.append(" instance.getValue('"+rhsCellMetadata.getValue('CellName')+"') ")
                else:
                    strBuffer.append(" '' ")
            elif condition.getValue('RHSParamType') == 'PrivateCell':
                if condition.getValue('RHSPrivateCellMetadata'):
                    rhsCellMetadata = self.session.get(condition.getValue('RHSPrivateCellMetadata'),self.CellMetadata)
                    strBuffer.append(" instance.getValue('"+rhsCellMetadata.getValue('CellDisplayName')+"') ")
                else:
                    strBuffer.append(" '' ")
            else:
                if condition.getValue('RHSValue'):
                    rhsValue=condition.getValue('RHSValue')
                    if cellType and int(cellType)==1 :
                        if (rhsValue[0]=='"' and rhsValue[len(rhsValue)-1]=='"') or (rhsValue[0]=="'" and rhsValue[len(rhsValue)-1]=="'") :
                            strBuffer.append(rhsValue)
                        else:
                            strBuffer.append("'"+rhsValue+"'")
                    else:
                        strBuffer.append(rhsValue)
                else:
                    strBuffer.append(" '' ")
        return ''.join(strBuffer)

    def getPermissionJstl(self,permissionType,condPermJstl):
        strBuffer = list()
        strBuffer.append("{if 'equal' == 'not equal'}\n")
        if len(condPermJstl)>0:
            strBuffer.append(condPermJstl)
        if permissionType is not None:
            strBuffer.append("{else}")
            strBuffer.append("{var permission = "+str(permissionType)+"}\n")
        strBuffer.append("{/if}\n")
        return ''.join(strBuffer)

    def hasGridView(self,gcell):
        if gcell.getValue('GridView'):
            return True;
        else:
            gridView_gridCell_refCell = self.GridView.getPublicCellMetadata('GridCell')
            gridViewList = self.session.getList(gcell,gridView_gridCell_refCell)
            if len(gridViewList) > 0:
                return True
        return False

    def getStyleName(self, styleId):
        if styleId:
            return  self.session.get(styleId, self.Style).getSheetName().replace(" ","_") or ""
        return ""

    def getReadOnlyStyle(self, gcell):
        if gcell.getValue('ReadOnlyStyle'):
            return self.getStyleName(gcell.getValue('ReadOnlyStyle'))
        elif gcell.getValue('ReadOnlyGlobalStyle'):
            return gcell.getValue('ReadOnlyGlobalStyle')
        else:
            return self.getJSTLClass(gcell)

    def getJSTLClass(self, gcell):
        if gcell.getValue('Style'):
            return self.getStyleName(gcell.getValue('Style'))
        elif gcell.getValue('GlobalStyle'):
            return gcell.getValue('GlobalStyle')

        if gcell.getValue('CellMetadata'):
            cellmeta = self.session.get(gcell.getValue('CellMetadata'),self.CellMetadata)
            if cellmeta.getValue('Style'):
                return self.getStyleName(cellmeta.getValue('Style'))
            elif cellmeta.getValue('GlobalStyle'):
                return cellmeta.getValue('GlobalStyle')
        return ""

    def getJstlAlign(self, gcell):
        alignStr = ""
        if gcell.getValue('VAlign'):
            alignStr += "valign='"+gcell.getValue('VAlign')+"'"
        else:
            alignStr += "valign='top'"
        if gcell.getValue('HAlign'):
            alignStr += "align='"+gcell.getValue('HAlign')+"'"
        return alignStr

    def isSubmit(self, gcell, cellmeta):
        if(gcell.getValue('ForceUpdate') == 2):
            return 0
        elif(gcell.getValue('ForceUpdate') == 1):
            return 1
        return self.getCellNodeCount(cellmeta)

    def getCellNodeCount(self, cellmeta):
        node_cell_refCell = self.Node.getPublicCellMetadata('CellMetadata')
        nodeList = self.session.getList(cellmeta,node_cell_refCell)
        if len(nodeList) > 0:
            return 1
        return 0

    def getPropertyValue(self, gcell, attrName, paramName='StaticValue'):
        prop_gridCell_refCell = self.Property.getPublicCellMetadata('GridCell')
        propertyList = self.session.getList(gcell,prop_gridCell_refCell)
        for property in propertyList:
            if(property.getValue('AttributeName') == attrName):
                return property.getValue(paramName) or ""
        return ''

    def getImportPropertyDict(self,gcell):
        prop_gridCell_refCell = self.Property.getPublicCellMetadata('GridCell')
        propertyList = self.session.getList(gcell,prop_gridCell_refCell)
        importDict = dict()
        for property in propertyList:
            if property.getValue('AttributeName') == 'import':
                if property.getValue('LHSCellMetadata'):
                    propertyDict = dict()
                    if property.getValue('StaticValue'):
                        propertyDict['CSVColumn'] = property.getValue('StaticValue')
                    if property.getValue('IsNatural'):
                        propertyDict['IsNaturalKey'] = property.getValue('IsNatural')
                    if property.getValue('Category'):
                        propertyDict['Category'] = property.getValue('Category')
                    if property.getValue('Format'):
                        propertyDict['Format'] = property.getValue('Format')
                    if property.getValue('RHSCellMetadata'):
                        propertyDict['OneToManyReference'] = property.getValue('RHSCellMetadata')
                    importDict[property.getValue('LHSCellMetadata')] = propertyDict
        return importDict

    def getWorkflowRenderPropertyList(self,gcell):
        prop_gridCell_refCell = self.Property.getPublicCellMetadata('GridCell')
        propertyList = self.session.getList(gcell,prop_gridCell_refCell)
        strBuffer = list()
        strBuffer.append('[')
        for property in propertyList:
            if(property.getValue('AttributeName') == 'Workflow'):
                lhsCellId = property.getValue('LHSCellMetadata')
                if lhsCellId:
                    lhsCell = self.session.get(lhsCellId,self.CellMetadata)
                    strBuffer.append("'"+lhsCell.getValue('CellName')+"',")
                    if property.getValue('ParamType') == 'Cell' and property.getValue('RHSCellMetadata'):
                        rhsCellId = property.getValue('RHSCellMetadata')
                        rhsCell = self.session.get(rhsCellId,self.CellMetadata)
                        strBuffer.append("'Cell',")
                        strBuffer.append("'"+rhsCell.getValue('CellName')+"',")
                    else:
                        strBuffer.append("'Value',")
                        strBuffer.append("'"+property.getValue('StaticValue')+"',")
                break
        rollbackUpdate = '0'
        if gcell.getValue('SaveUpdateOnSubmit'):
            rollbackUpdate = str(gcell.getValue('SaveUpdateOnSubmit'))
        strBuffer.append(rollbackUpdate)
        strBuffer.append(']')
        return ''.join(strBuffer)

    def getCellFormat(self, cellmeta):
        format = "#,###"
        if cellmeta.getValue('FinalFormat'):
            format = cellmeta.getValue('FinalFormat')
        return str(format)

    def getRangeValue(self,cellmeta):
        if(cellmeta.getValue('Range')):
            rangeVal = ""
            range = self.session.get(cellmeta.getValue('Range'),self.Range)
            rangeValue_range_refCell = self.RangeValue.getPublicCellMetadata('Range')
            rangeValList = self.session.getList(range,rangeValue_range_refCell)
            rangeValList.sort(lambda x, y: cmp(x.getValue('CreatedAt'), y.getValue('CreatedAt')))
            rangeVal = "["
            for rangeValue in rangeValList:
                #urlencode is added for comma value in rangeValue
                actualVal = self.urlEncode(rangeValue.getValue('Value'))
                if(rangeVal == "[" and actualVal):
                    rangeVal += "'"+actualVal+"'"
                elif(rangeValue.getValue('Value')):
                    rangeVal += ",'"+actualVal+"'"
            rangeVal += "]"
            return rangeVal
        else:
            return "[]"

    def getActivityStatus(self,activity):
        from orangescape.model.engine.execution.ProcessUtil import getProcessCell_PrefixName
        from orangescape.model.server.Development import ActivityDefinitionDevModel
        activityWrapper = ActivityDefinitionDevModel(activity)
        return getProcessCell_PrefixName(activityWrapper)+"Status"

    def getValidationJstl(self, gcell, validationList, cellName, containedGridId):
        strBuffer = list()
        if len(validationList) > 0:
            validationList.sort(lambda x, y: cmp(x.getValue('CreatedAt'), y.getValue('CreatedAt')))
            strBuffer.append("{var hasError = false}\n")
            for validation in validationList:
                #when criteria in validation
                strBuffer.append("{var performValidation = true}\n")
                criteria_validation_refCell = self.Criteria.getPublicCellMetadata('Validation_When')
                validationCriteriaList = self.session.getList(validation,criteria_validation_refCell)
                if len(validationCriteriaList) > 0:
                    criteriaCondStr = self.constructCriteria(validationCriteriaList[0])
                    if(len(criteriaCondStr) > 0):
                        strBuffer.append("{if ")
                        strBuffer.append(criteriaCondStr)
                        strBuffer.append("}\n")
                        strBuffer.append("{var performValidation = true}\n")
                        strBuffer.append("{else}\n")
                        strBuffer.append("{var performValidation = false}\n")
                        strBuffer.append("{/if}\n")

                strBuffer.append("{if performValidation && !hasError}\n")
                strBuffer.append("{var validatonLhsValue=instance.getValue('"+cellName+"')}\n")
                if validation.getValue('Criteria')  == 'Text_length':
                    strBuffer.append("{if validatonLhsValue != null}\n")
                    strBuffer.append("{var validatonLhsValue = validatonLhsValue.length}\n")
                    strBuffer.append("{/if}\n")
                if(validation.getValue('ParamType') is None or validation.getValue('ParamType') == "Value"):
                    if(validation.getValue('Criteria') == 'Text'):
                        strBuffer.append("{var validatonRhsValue = "+self.getValidationValue(validation,'TextValue')+"}\n")
                    else:
                        strBuffer.append("{var validatonRhsValue = "+self.getValidationValue(validation,'Value')+"}\n")
                        strBuffer.append("{var validatonMinimumValue = "+self.getValidationValue(validation,'Minimum')+"}\n")
                        strBuffer.append("{var validatonMaximumValue = "+self.getValidationValue(validation,'Maximum')+"}\n")
                else:
                    strBuffer.append("{var validatonRhsValue = "+self.getValidationCellName(validation,'ValueCellMetadata')+"}\n")
                    strBuffer.append("{var validatonMinimumValue = "+self.getValidationCellName(validation,'MinimumCellMetadata')+"}\n")
                    strBuffer.append("{var validatonMaximumValue = "+self.getValidationCellName(validation,'MaximumCellMetadata')+"}\n")

                if validation.getValue('Operator') == 'between':
                    strBuffer.append("{if validatonLhsValue < validatonMinimumValue || validatonLhsValue > validatonMaximumValue}\n")
                    strBuffer.append("{var hasError = true}\n")
                    strBuffer.append("{/if}\n")
                elif validation.getValue('Operator') == 'not_between':
                    strBuffer.append("{if validatonLhsValue >= validatonMinimumValue || validatonLhsValue <= validatonMaximumValue}\n")
                    strBuffer.append("{var hasError = true}\n")
                    strBuffer.append("{/if}\n")
                elif validation.getValue('Operator') == 'equal_to':
                    strBuffer.append("{if validatonLhsValue != validatonRhsValue}\n")
                    strBuffer.append("{var hasError = true}\n")
                    strBuffer.append("{/if}\n")
                elif validation.getValue('Operator') == 'not_equal_to':
                    strBuffer.append("{if validatonLhsValue == validatonRhsValue}\n")
                    strBuffer.append("{var hasError = true}\n")
                    strBuffer.append("{/if}\n")
                elif validation.getValue('Operator') == 'greater_than':
                    strBuffer.append("{if validatonLhsValue <= validatonRhsValue}\n")
                    strBuffer.append("{var hasError = true}\n")
                    strBuffer.append("{/if}\n")
                elif validation.getValue('Operator') == 'less_than':
                    strBuffer.append("{if validatonLhsValue >= validatonRhsValue}\n")
                    strBuffer.append("{var hasError = true}\n")
                    strBuffer.append("{/if}\n")
                elif validation.getValue('Operator') == 'greater_than_or_equal_to':
                    strBuffer.append("{if validatonLhsValue < validatonRhsValue}\n")
                    strBuffer.append("{var hasError = true}\n")
                    strBuffer.append("{/if}\n")
                elif validation.getValue('Operator') == 'less_than_or_equal_to':
                    strBuffer.append("{if validatonLhsValue > validatonRhsValue}\n")
                    strBuffer.append("{var hasError = true}\n")
                    strBuffer.append("{/if}\n")

                strBuffer.append("{if hasError}\n")
                strBuffer.append("${constructErrorMessage('"+cellName+"',"+self.getValidationValue(validation,'ErrorType')+","+self.getValidationValue(validation,'ErrorMessage')+",'"+containedGridId+"')}\n")
                strBuffer.append("{/if}\n")

                if validation.getValue('InputMessage'):
                    strBuffer.append("${constructInputMessage('"+cellName+"',"+self.getValidationValue(validation,'InputMessage')+")}\n")

                strBuffer.append("{/if}\n")
                if (gcell.getValue('ValidationOper') == 1 or gcell.getValue('ValidationOper') == "1"):
                    strBuffer.append("{var hasError = false}\n")

        return ''.join(strBuffer)

    def escape(self,html):
        return html.replace("'", "\\'")

    def urlEncode(self, val):
        import urllib
        return urllib.quote(val)

    def getValidationValue(self, validation,propertyName):
        if validation.getValue(propertyName) is not None:
            if propertyName == 'Value' or propertyName == 'Minimum' or propertyName == 'Maximum':
                return self.escape(str(validation.getValue(propertyName)))
            else:
                return "'"+self.escape(str(validation.getValue(propertyName)))+"'"
        else:
            return "null"

    def getValidationCellName(self, validation,propertyName):
        if validation.getValue(propertyName):
            cellMetadata = self.session.get(validation.getValue(propertyName),self.CellMetadata)
            return "instance.getValue('"+cellMetadata.getValue('CellName')+"')"
        else:
            return "null"

    def getValidationGridList(self, gcell):
        strBuffer = list()
        #back ward compatibility code need to be removed
        validationGrid_gridCell_refCell = self.ValidationGrid.getPublicCellMetadata('GridCell')
        validatationGridList = self.session.getList(gcell, validationGrid_gridCell_refCell)
        if len(validatationGridList) > 0:
            gridViewIdList = [validatation.getValue('GridView') for validatation in validatationGridList]
        else:
            gridViewIdList = list()
            self.getGridViewIdList(gcell, self.rootGrid, gridViewIdList)

        n = len(gridViewIdList)
        for gridViewId in gridViewIdList:
            strBuffer.append(gridViewId)
            n = n - 1
            if n > 0:
                strBuffer.append(",")
        return ''.join(strBuffer)

    def getGridViewIdList(self, submitCell, gridView, gridViewIdList, excludeValidation=None, includeValidation=None):
        if excludeValidation is None:
            excludeValidation = self.hasExcludeValidation(submitCell, gridView.getSheetId())
        elif self.hasExcludeValidation(submitCell,gridView.getSheetId()) is not None:
            excludeValidation = self.hasExcludeValidation(submitCell,gridView.getSheetId())
            includeValidation = None
        elif includeValidation is None:
            includeValidation = self.hasIncludeValidation(excludeValidation, gridView.getSheetId())

        if excludeValidation is not None and includeValidation is None:
            gridViewIdList.append(gridView.getSheetId())

        gridRow_gridView_refCell = self.GridRow.getPublicCellMetadata('GridView')
        gridRowList = self.session.getList(gridView,gridRow_gridView_refCell)
        gridRowList.sort(lambda x, y: cmp(x.getValue('RowNumber'), y.getValue('RowNumber')))
        for gridRow in gridRowList:
            gridCell_gridRow_refCell = self.GridCell.getPublicCellMetadata('GridRow')
            gridCellList = self.session.getList(gridRow,gridCell_gridRow_refCell)
            gridCellList.sort(lambda x, y: cmp(x.getValue('ColumnNumber'), y.getValue('ColumnNumber')))
            for gridCell in gridCellList:
                gridView_gridCell_refCell = self.GridView.getPublicCellMetadata('GridCell')
                nestedGridViewList = self.session.getList(gridCell,gridView_gridCell_refCell)
                if(gridCell.getValue('GridView')):
                    publicGrid = self.session.get(gridCell.getValue('GridView'),self.GridView)
                    self.getGridViewIdList(submitCell,publicGrid,gridViewIdList,excludeValidation,includeValidation)
                elif len(nestedGridViewList)>0:
                    for nestedGrid in nestedGridViewList:
                        self.getGridViewIdList(submitCell, nestedGrid, gridViewIdList, excludeValidation, includeValidation)

    def hasExcludeValidation(self,gridCell, gridViewId):
        excludeValidationGrid_gridCell_refCell = self.ExcludeValidationGrid.getPublicCellMetadata('GridCell')
        excludeValidationList = self.session.getList(gridCell, excludeValidationGrid_gridCell_refCell)
        for excludeValidation in excludeValidationList:
            if excludeValidation.getValue('GridView') == gridViewId:
                return excludeValidation
        return None

    def hasIncludeValidation(self, excludeValidation, gridViewId):
        includeValidationGrid_gridCell_refCell = self.IncludeValidationGrid.getPublicCellMetadata('ExcludeValidationGrid')
        includeValidationList = self.session.getList(excludeValidation, includeValidationGrid_gridCell_refCell)
        for includeValidation in includeValidationList:
            if includeValidation.getValue('GridView') == gridViewId:
                return includeValidation
        return None

    def getValue(self,obj,cellName):
        return obj.getValue(cellName) or ""