PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/from_1.3-1.3.1/helpers/Preferences.cfc

https://bitbucket.org/asfusion/mango-updates
ColdFusion CFScript | 292 lines | 227 code | 65 blank | 0 comment | 2 complexity | 87956db63367f45e239e4b624d7c9438 MD5 | raw file
  1. <!---
  2. Implementation of the Java Preferences API.
  3. Although it doesn't implement the same functions as the java.util.prefs.Preferences, it is able to parse
  4. and modify files generated by the Java API.
  5. It can be used to store any type of configuration settings or user
  6. preferences whenever programatic access and manipulation is desired.
  7. Sample usage:
  8. <cfset preferencesFile = GetDirectoryFromPath(GetCurrentTemplatePath()) & "myPreferences.cfm" />
  9. <cfset preferences = createObject("component","components.utilities.Preferences").init(preferencesFile) />
  10. Path: /userSettings/tom
  11. Key: name
  12. Value: Tom
  13. <cfset preferences.put("/userSettings/tom","name", "Tom") />
  14. Path: /userSettings/tom
  15. Key: themeColor
  16. Value: red
  17. <cfset preferences.put("/userSettings/tom","themeColor", "red") />
  18. --------------------------------------------------
  19. Copyright 2007 Laura Arguello
  20. Licensed under the Apache License, Version 2.0 (the "License"); you may not use the files in this package except in compliance with the License. You may obtain a copy of the License at
  21. http://www.apache.org/licenses/LICENSE-2.0
  22. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
  23. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24. See the License for the specific language governing permissions and limitations under the License.
  25. --->
  26. <cfcomponent>
  27. <cfset variables.xmlData = xmlnew(false) />
  28. <cfset variables.currentNode = "/preferences/root" />
  29. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  30. <cffunction name="init" access="public" output="false" hint="Contructor">
  31. <cfargument name="initialData" type="String" required="false" default="" />
  32. <cfargument name="node" type="String" required="false" default="/preferences/root" hint="Starting node. Not required" />
  33. <cfset variables.currentNode = arguments.node />
  34. <cfif len(arguments.initialData)>
  35. <!--- remove cfsilent just in case --->
  36. <cfset arguments.initialData = trim(replacenocase(replacenocase(arguments.initialData,"<cfsilent>",""),"</cfsilent>","")) />
  37. <cfset importPreferences(XmlParse(arguments.initialData)) />
  38. <cfelse>
  39. <cfset createNew() />
  40. </cfif>
  41. <cfreturn this />
  42. </cffunction>
  43. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  44. <cffunction name="get" access="public" output="false" returntype="any" hint="Returns the value associated with the specified key in this preference node. Returns the specified default if there is no value associated with the key.">
  45. <cfargument name="pathName" type="String" required="false" hint="Path to preference node" />
  46. <cfargument name="key" type="String" required="true" hint="key whose associated value is to be returned" />
  47. <cfargument name="default" type="String" required="false" default="" hint="the value to be returned in the event that this preference node has no value associated with key" />
  48. <cfset var preference = arguments.default />
  49. <cfset var searchPath = variables.currentNode />
  50. <cfset var node = "" />
  51. <cfloop list="#arguments.pathName#" index="node" delimiters="/">
  52. <cfset searchPath = searchPath & '/node[@name="#node#"]' />
  53. </cfloop>
  54. <cfset searchPath = searchPath & '/map/entry[@key="#key#"]' />
  55. <!--- find node in tree --->
  56. <cfset node = XmlSearch(variables.xmlData, searchPath) />
  57. <cfif arraylen(node)>
  58. <cfset preference = node[1].xmlattributes.value />
  59. </cfif>
  60. <cfreturn preference />
  61. </cffunction>
  62. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  63. <cffunction name="remove" access="public" output="false" returntype="void" hint="Removes the value associated with the specified key in this preference node, if any.">
  64. <cfargument name="pathName" type="String" required="false" hint="Path to preference node" />
  65. <cfargument name="key" type="String" required="true" hint="key whose mapping is to be removed from the preference node." />
  66. <cfset var mapEntries = "" />
  67. <cfset var node = "" />
  68. <cfset var i = 0 />
  69. <cfif nodeexists(arguments.pathName)>
  70. <cfset node = getNode(arguments.pathName) />
  71. <cfif structkeyexists(node, "map")>
  72. <cfloop from="1" to="#arraylen(node.map.xmlChildren)#" index="i">
  73. <cfif node.map.xmlChildren[i].xmlName EQ "entry" AND
  74. node.map.xmlChildren[i].xmlAttributes["key"] EQ arguments.key>
  75. <cfset arraydeleteat(node.map.xmlChildren, i) />
  76. <cfbreak />
  77. </cfif>
  78. </cfloop>
  79. </cfif>
  80. </cfif>
  81. <cfset flush() />
  82. <cfreturn />
  83. </cffunction>
  84. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  85. <cffunction name="nodeExists" access="public" output="false" returntype="boolean">
  86. <cfargument name="pathName" type="String" required="false" />
  87. <cfset var searchPath = variables.currentNode />
  88. <cfset var node = "" />
  89. <cfloop list="#arguments.pathName#" index="node" delimiters="/">
  90. <cfset searchPath = searchPath & '/node[@name="#node#"]' />
  91. </cfloop>
  92. <!--- find node in tree --->
  93. <cfset node = XmlSearch(variables.xmlData, searchPath) />
  94. <cfreturn arraylen(node) />
  95. </cffunction>
  96. <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  97. <cffunction name="getNode" access="private" output="false" returntype="xml">
  98. <cfargument name="pathName" type="String" required="false" hint="Path to preference node" />
  99. <cfset var searchPath = variables.currentNode />
  100. <cfset var node = "" />
  101. <cfloop list="#arguments.pathName#" index="node" delimiters="/">
  102. <cfset searchPath = searchPath & '/node[@name="#node#"]' />
  103. </cfloop>
  104. <!--- find node in tree --->
  105. <cfset node = XmlSearch(variables.xmlData, searchPath) />
  106. <!--- if not found, this will throw an error --->
  107. <cfreturn node[1] />
  108. </cffunction>
  109. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  110. <cffunction name="put" access="public" output="false" returntype="void" hint="Associates the specified value with the specified key in the given preference node">
  111. <cfargument name="pathName" type="String" required="false" hint="Path to preference node" />
  112. <cfargument name="key" type="String" required="true" hint="Key with which the specified value is to be associated." />
  113. <cfargument name="value" type="String" required="false" hint="Value to be associated with the specified key" />
  114. <cfset var newNode = "" />
  115. <cfset var node = "" />
  116. <cfset var entry = "" />
  117. <cfset var i = 0 />
  118. <cfset var found = false />
  119. <cfif NOT nodeexists(arguments.pathName)>
  120. <cfset createNode(arguments.pathName) />
  121. </cfif>
  122. <cfset node = getNode(arguments.pathName) />
  123. <!--- find key --->
  124. <cfloop from="1" to="#arraylen(node.map.xmlChildren)#" index="i">
  125. <cfif node.map.xmlChildren[i].xmlAttributes["key"] EQ arguments.key>
  126. <cfset found = true />
  127. <!--- change value --->
  128. <cfset node.map.xmlChildren[i].xmlAttributes["value"] = arguments.value />
  129. <cfbreak>
  130. </cfif>
  131. </cfloop>
  132. <cfif NOT found>
  133. <cfset newNode = XmlElemNew(variables.xmlData,"entry") />
  134. <cfset newNode.XmlAttributes["key"] = arguments.key />
  135. <cfset newNode.XmlAttributes["value"] = arguments.value />
  136. <cfset arrayappend(node.map.xmlChildren,newNode) />
  137. </cfif>
  138. <cfset flush() />
  139. </cffunction>
  140. <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  141. <cffunction name="removeNode" access="public" output="false" returntype="void" hint="Removes the given preference node and all of its descendants">
  142. <cfargument name="pathName" type="String" required="true" hint="Path to node to remove" />
  143. <cfset var parentPath = listDeleteAt(arguments.pathName, listlen(arguments.pathName, "/"), "/") />
  144. <cfset var parent = "" />
  145. <cfset var i = 0 />
  146. <cfset var nodeName = listlast(arguments.pathName, "/") />
  147. <cfif nodeexists(arguments.pathName)>
  148. <cfset parent = getNode(parentPath) />
  149. <cfloop from="1" to="#arraylen(parent.node)#" index="i">
  150. <cfif parent.node[i].xmlAttributes.name EQ nodeName>
  151. <!--- remove it --->
  152. <cfset arraydeleteat(parent.xmlchildren, xmlChildPos(parent, "node", i)) />
  153. <cfbreak />
  154. </cfif>
  155. </cfloop>
  156. </cfif>
  157. <cfset flush() />
  158. <cfreturn />
  159. </cffunction>
  160. <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  161. <cffunction name="exportSubtree" access="public" output="false" returntype="xml">
  162. <cfreturn duplicate(variables.xmlData) />
  163. </cffunction>
  164. <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  165. <cffunction name="exportSubtreeAsStruct" access="public" output="false" returntype="struct" hint="Returns a structure containing the keys and values of the preferences from given node">
  166. <cfargument name="pathName" type="String" required="false" default="/" hint="Path to node from which to export" />
  167. <!--- go to node --->
  168. <cfset var node = getNode(arguments.pathName) />
  169. <cfset var map = structnew() />
  170. <cfset var i = 0 />
  171. <cfloop from="1" to="#arraylen(node.map.xmlChildren)#" index="i">
  172. <cfset map[node.map.xmlChildren[i].xmlAttributes["key"]] = node.map.xmlChildren[i].xmlAttributes["value"] />
  173. </cfloop>
  174. <cfloop from="1" to="#arraylen(node.xmlChildren)#" index="i">
  175. <!--- ignore the map node --->
  176. <cfif node.xmlChildren[i].xmlname EQ "node">
  177. <cfset map[node.xmlChildren[i].xmlAttributes["name"]] = exportSubtreeAsStruct(arguments.pathName & "/" & node.xmlChildren[i].xmlAttributes["name"]) />
  178. </cfif>
  179. </cfloop>
  180. <cfreturn map />
  181. </cffunction>
  182. <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  183. <cffunction name="createNode" access="private" output="false" returntype="void">
  184. <cfargument name="pathName" type="String" required="true" />
  185. <cfset var nodePath = "" />
  186. <cfset var searchPath = variables.currentNode />
  187. <cfset var node = "" />
  188. <cfset var parentPath = "" />
  189. <cfset var parent = "" />
  190. <cfset var newNode = "" />
  191. <cfset var newMap = "" />
  192. <cfloop list="#arguments.pathName#" index="node" delimiters="/">
  193. <cfset nodePath = nodePath & "/" & node />
  194. <cfset parentPath = searchPath />
  195. <cfset searchPath = searchPath & '/node[@name="#node#"]' />
  196. <cfif NOT nodeexists(nodePath)>
  197. <cfset newNode = XmlElemNew(variables.xmlData, "node") />
  198. <cfset newMap = XmlElemNew(variables.xmlData, "map") />
  199. <cfset parent = XmlSearch(variables.xmlData, parentPath) />
  200. <cfset newNode.XmlAttributes["name"] = node />
  201. <cfset arrayappend(newNode.xmlChildren,newMap) />
  202. <cfset arrayappend(parent[1].xmlChildren,newNode) />
  203. </cfif>
  204. </cfloop>
  205. </cffunction>
  206. <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  207. <cffunction name="importPreferences" access="public" output="false" returntype="void">
  208. <cfargument name="data" type="xml" required="true" />
  209. <cfset variables.xmlData = arguments.data />
  210. </cffunction>
  211. <!--- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  212. <cffunction name="createNew" access="private" output="false" returntype="void">
  213. <cfxml casesensitive="false" variable="variables.xmlData"><?xml version="1.0" encoding="UTF-8"?>
  214. <!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
  215. <preferences EXTERNAL_XML_VERSION="1.0">
  216. <root type="system">
  217. <map />
  218. </root>
  219. </preferences>
  220. </cfxml>
  221. <cfset flush() />
  222. </cffunction>
  223. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  224. <cffunction name="flush" access="public" output="false" returntype="void" hint="Saves any changes in the contents of the preferences to the persistent store">
  225. <!--- doesn't do anything... --->
  226. </cffunction>
  227. </cfcomponent>