option explicit class classStateHandler private m_xmlStates public sub class_initialize resetStates end sub public sub setFromStatesString(byVal statesString) dim sPair dim iPair dim sNameValue dim sName dim sValue dim arrStateName(30) dim arrNumberName(30) dim arrStringName(30) dim arrStateValue(30) dim arrNumberValue(30) dim arrStringValue(30) dim sTypeIndexSubtype dim sType dim sIndex dim sSubtype dim i dim vValue if statesString <> "" then for i = lBound(arrStateName) to uBound(arrStateName) arrStateName(i) = "" arrNumberName(i) = "" arrStringName(i) = "" next sPair = split(statesString, "&") for iPair = lBound(sPair) to uBound(sPair) sNameValue = split( sPair(iPair), "=" ) sName = sNameValue( lBound(sNameValue) ) sValue = sNameValue( uBound(sNameValue) ) sTypeIndexSubtype = split(sName, "_") sType = sTypeIndexSubtype( lBound(sTypeIndexSubtype) ) sIndex = sTypeIndexSubtype( lBound(sTypeIndexSubtype) + 1 ) sSubtype = sTypeIndexSubtype( lBound(sTypeIndexSubtype) + 2 ) select case sType case "state" i = cLng(sIndex) if i >= lBound(arrStateName) and i <= uBound(arrStateName) then if sSubtype = "name" then arrStateName(i) = sValue elseif sSubtype = "value" then arrStateValue(i) = sValue end if end if case "number" i = cLng(sIndex) if i >= lBound(arrNumberName) and i <= uBound(arrNumberName) then if sSubtype = "name" then arrNumberName(i) = sValue elseif sSubtype = "value" then arrNumberValue(i) = sValue end if end if case "string" i = cLng(sIndex) if i >= lBound(arrStringName) and i <= uBound(arrStringName) then if sSubtype = "name" then arrStringName(i) = sValue elseif sSubtype = "value" then arrStringValue(i) = sValue end if end if end select next for i = lBound(arrStateName) to uBound(arrStateName) if arrStateName(i) <> "" then vValue = cBool(arrStateValue(i) = "true") setState arrStateName(i), vValue end if if arrNumberName(i) <> "" then vValue = arrNumberValue(i) if vValue = "" then vValue = 0 end if vValue = cLng(vValue) setNumber arrNumberName(i), vValue end if if arrStringName(i) <> "" then vValue = cStr( arrStringValue(i) ) setString arrStringName(i), vValue end if next end if end sub public function getSessionDataAsString dim sXml sXml = m_xmlStates.xml sXml = replace(sXml, "/>", "/>" & vbNewline & " ") getSessionDataAsString = sXml end function public sub setSessionDataFromXml(byRef xmlSession) dim xPath dim oStates dim oState resetStates xPath = "//states/*" set oStates = xmlSession.selectNodes(xPath) for each oState in oStates select case oState.nodeName case "state" processSetNode oState case "number" processNumberNode oState case "string" processStringNode oState end select next end sub public sub resetStates set m_xmlStates = getXmlString("") end sub public sub handlePreStates(byRef station) dim oStates dim oState dim xPath dim ifElement xPath = "if" set ifElement = station.selectSingleNode(xPath) if not (ifElement is nothing) then xPath = "state | number| string" set oStates = station.selectNodes(xPath) for each oState in oStates select case oState.nodeName case "state" processSetNode oState case "number" processNumberNode oState case "string" processStringNode oState end select next end if end sub public function getNodeState(byRef stateNode) dim thisCheck dim checkValue thisCheck = true checkValue = stateNode.getAttribute("check") if not isNull(checkValue) then checkValue = replace(checkValue, "equal", "=") checkValue = replace(checkValue, "greater", ">") checkValue = replace(checkValue, "lower", "<") checkValue = replace(checkValue, "= >", "> =") checkValue = replace(checkValue, "= <", "< =") checkValue = replace(checkValue, "> =", ">=") checkValue = replace(checkValue, "< =", "<=") checkValue = replace(checkValue, "=>", ">=") checkValue = replace(checkValue, "=<", "<=") checkValue = replace(checkValue, "'", """") checkValue = replaceAllValuesQuote(checkValue) if checkValue <> "" then thisCheck = eval(checkValue) thisCheck = cBool(thisCheck) end if end if getNodeState = thisCheck end function public sub setStates(byRef child) select case child.nodeName case "state" processSetNode child case "number" processNumberNode child case "string" processStringNode child end select end sub public sub setState(byVal thisName, byVal thisValue) dim thisElement thisValue = returnIf(thisValue, "true", "false") set thisElement = setValue("state", thisName, thisValue) if thisValue = "false" then thisElement.parentNode.removeChild thisElement end if end sub public sub setString(byVal thisName, byVal thisValue) dim thisElement thisValue = replaceAllValues(thisValue) set thisElement = setValue("string", thisName, thisValue) end sub public sub setNumber(byVal thisName, byVal thisValue) dim thisElement thisValue = replaceAllValues(thisValue) if thisValue <> "" then thisValue = eval(thisValue) end if set thisElement = setValueNumber(thisName, thisValue) end sub public sub setNumberWithMinMax(byVal thisName, byVal thisValue, byVal min, byVal max) dim thisElement thisValue = replaceAllValues(thisValue) if thisValue <> "" then thisValue = eval(thisValue) end if set thisElement = setValueNumberWithMinMax(thisName, thisValue, min, max) end sub public function getState(byVal thisName) dim thisValue thisValue = getValue("state", thisName) thisValue = cBool(thisValue = "true") getState = thisValue end function public function getNumber(byVal thisName) dim thisValue thisValue = getValue("number", thisName) if thisValue = "" then thisValue = 0 end if getNumber = thisValue end function public function getString(byVal thisName) dim thisValue thisValue = getValue("string", thisName) getString = thisValue end function public function replaceAllValues(byVal text) const quoteString = false replaceAllValues = cStr( replaceAllValuesOption(text, quoteString) ) end function private function replaceAllValuesQuote(byVal text) const quoteString = true replaceAllValuesQuote = cStr( replaceAllValuesOption(text, quoteString) ) end function private function replaceAllValuesOption(byVal text, byVal quoteString) text = replaceValuesOf("string", text, false, quoteString) text = replaceValuesOf("number", text, false, quoteString) text = replaceValuesOf("state", text, false, quoteString) text = replaceValuesOf("number", text, true, quoteString) text = replaceFunctionValues(text) replaceAllValuesOption = cStr(text) end function public sub addVisits(byVal stationId) dim allName dim thisName allName = "qmlVisits(*)" thisName = "qmlVisits(" & stationId & ")" setNumber allName, getNumber(allName) + 1 setNumber thisName, getNumber(thisName) + 1 end sub public function getStatesInformation(byVal stationId) dim xhtml dim xmlTemplate dim stateList dim numberList dim stringList dim xPath dim stateElements dim stateElement dim thisValue dim thisName dim internalState dim i dim sStart dim sEnd dim min dim max stateList = "" numberList = "" stringList = "" for i = 1 to 2 xPath = "//state|//number|//string" set stateElements = m_xmlStates.selectNodes(xPath) for each stateElement in stateElements thisName = stateElement.getAttribute("name") thisValue = stateElement.getAttribute("value") internalState = inStr(thisName, "qml") = 1 if i = 1 then sStart = "
  • " sEnd = "
  • " else ' if i = 2 then sStart = "
  • " sEnd = "
  • " end if if ( i = 1 and (not internalState) ) or (i = 2 and internalState) then select case stateElement.nodeName case "state" stateList = stateList & sStart & thisName & " = " & thisValue & sEnd case "number" numberList = numberList & sStart & thisName & " = " & thisValue & sEnd min = stateElement.getAttribute("min") max = stateElement.getAttribute("max") if ( not isNull(min) ) or ( not isNull(max) ) then numberList = numberList & " (min=" & min & ", max=" & max & ")" end if case "string" stringList = stringList & sStart & thisName & " = """ & thisValue & """" & sEnd end select end if next next if stateList <> "" then stateList = "" end if if numberList <> "" then numberList = "" end if if stringList <> "" then stringList = "" end if set xmlTemplate = getXml("script/states_node.xml") xhtml = xmlTemplate.documentElement.xml ' xhtml = replace( xhtml, "[xml]", replace( xmlToText(m_xmlStates.xml) , ">", ">
    ") ) xhtml = replace(xhtml, "[stationId]", """" & stationId & """") xhtml = replace(xhtml, "[stateList]", stateList) xhtml = replace(xhtml, "[numberList]", numberList) xhtml = replace(xhtml, "[stringList]", stringList) getStatesInformation = xhtml end function ' private __________________________________________________________ private function getValue(byVal thisNodeName, byVal thisName) dim thisElement dim xPath dim thisValue dim min dim max thisValue = "" xPath = "//" & thisNodeName & "[@name = '" & thisName & "']" set thisElement = m_xmlStates.selectSingleNode(xPath) if not (thisElement is nothing) then thisValue = thisElement.getAttribute("value") if isNull(thisValue) then thisValue = "" elseif thisNodeName = "number" then min = thisElement.getAttribute("min") max = thisElement.getAttribute("max") if not isNull(min) then if cLng(thisValue) < cLng(min) then thisValue = min end if end if if not isNull(max) then if cLng(thisValue) > cLng(max) then thisValue = max end if end if end if end if getValue = thisValue end function private function setValue(byVal thisNodeName, byVal thisName, byVal thisValue) dim thisElement dim xPath xPath = "//" & thisNodeName & "[@name = '" & thisName & "']" set thisElement = m_xmlStates.selectSingleNode(xPath) if thisElement is nothing then set thisElement = m_xmlStates.createElement(thisNodeName) set thisElement = m_xmlStates.documentElement.appendChild(thisElement) end if thisElement.setAttribute "name", thisName thisElement.setAttribute "value", thisValue set setValue = thisElement end function private function setValueNumber(byVal thisName, byVal thisValue) dim thisElement dim xPath dim thisNodeName dim min dim max thisNodeName = "number" xPath = "//" & thisNodeName & "[@name = '" & thisName & "']" set thisElement = m_xmlStates.selectSingleNode(xPath) if thisElement is nothing then set thisElement = m_xmlStates.createElement(thisNodeName) set thisElement = m_xmlStates.documentElement.appendChild(thisElement) end if min = thisElement.getAttribute("min") max = thisElement.getAttribute("max") if not isNull(min) then thisElement.setAttribute "min", min if cLng(thisValue) < cLng(min) then thisValue = min end if end if if not isNull(max) then thisElement.setAttribute "max", max if cLng(thisValue) > cLng(max) then thisValue = max end if end if thisElement.setAttribute "name", thisName thisElement.setAttribute "value", thisValue set setValueNumber = thisElement end function private function setValueNumberWithMinMax(byVal thisName, byVal thisValue, byVal min, byVal max) dim thisElement dim xPath dim thisNodeName thisNodeName = "number" xPath = "//" & thisNodeName & "[@name = '" & thisName & "']" set thisElement = m_xmlStates.selectSingleNode(xPath) if thisElement is nothing then set thisElement = m_xmlStates.createElement(thisNodeName) set thisElement = m_xmlStates.documentElement.appendChild(thisElement) end if if not isNull(min) then thisElement.setAttribute "min", min if cLng(thisValue) < cLng(min) then thisValue = min end if end if if not isNull(max) then thisElement.setAttribute "max", max if cLng(thisValue) > cLng(max) then thisValue = max end if end if thisElement.setAttribute "name", thisName thisElement.setAttribute "value", thisValue set setValueNumberWithMinMax = thisElement end function private function getIsTrue(byVal state, byVal relation) dim isTrue isTrue = false if state then isTrue = true elseif relation = "and" then isTrue = false end if getIsTrue = cBool(isTrue) end function private sub processSetNode(byRef setNode) dim state dim stateNew state = lCase( setNode.getAttribute("name") ) stateNew = cBool( "true" = setNode.getAttribute("value") ) setState state, stateNew end sub private sub processNumberNode(byRef numberNode) dim numberName dim numberValue dim min dim max numberName = numberNode.getAttribute("name") numberValue = numberNode.getAttribute("value") min = numberNode.getAttribute("min") max = numberNode.getAttribute("max") setNumberWithMinMax numberName, numberValue, min, max end sub private sub processStringNode(byRef stringNode) dim stringName dim stringValue stringName = stringNode.getAttribute("name") stringValue = stringNode.getAttribute("value") stringValue = replaceValuesOf("string", stringValue, false, false) setString stringName, stringValue end sub private sub setVisitsFromString(byVal strng) ' format "visits(start)=1" or "visits(*)=1" dim splitted splitted = split(strng, "=") setNumber splitted(0), splitted(1) end sub private function replaceValuesOf(byVal sValueType, byVal text, byVal forceDefault, byVal quoteString) const startString = "[" dim startsAt dim endsAt dim lengthOf dim valueName dim splitted dim sValue dim doUse startsAt = 0 do if isNull(text) then text = "" end if startsAt = instr(startsAt + 1, text, startString) if startsAt >= 1 then lengthOf = instr( mid( text, startsAt + len(startString) ), "]" ) if lengthOf >= 1 then valueName = mid(text, startsAt + len(startString), lengthOf - 1) doUse = false select case sValueType case "state" sValue = getState(valueName) sValue = returnIf( cBool(sValue), "true", "false" ) doUse = cBool(sValue) or forceDefault case "number" sValue = getNumber(valueName) doUse = sValue <> 0 or forceDefault case "string" sValue = getString(valueName) if sValue <> "" then if quoteString then sValue = """" & sValue & """" else sValue = "" & sValue & "" end if end if doUse = sValue <> "" or forceDefault end select if doUse then text = left(text, startsAt - 1) & sValue & _ mid( text, startsAt + len(startString) + lengthOf ) end if end if end if loop until not startsAt >= 1 replaceValuesOf = text end function private function replaceFunctionValues(byVal text) dim oldText do oldText = text text = doReplaceFunctionValues(text) if oldText = text then exit do end if loop replaceFunctionValues = text end function private function doReplaceFunctionValues(byVal text) const startString = "{" dim startsAt dim endsAt dim lengthOf dim newText dim functionString dim functionOk dim returnValue dim oInlineFunction newText = text startsAt = instr(newText, startString) if startsAt >= 1 then lengthOf = instr( mid( newText, startsAt + len(startString) ), "}" ) if lengthOf >= 1 then functionString = mid(newText, startsAt + len(startString), lengthOf - 1) set oInlineFunction = new classInlineFunction oInlineFunction.setInlineString functionString oInlineFunction.setXmlStates m_xmlStates oInlineFunction.process returnValue = oInlineFunction.getXhtml newText = left(newText, startsAt - 1) & returnValue & _ mid( newText, startsAt + len(startString) + lengthOf ) end if end if doReplaceFunctionValues = newText end function end class