A
download WebtopRoot.cfc
Language: ColdFusion
License: CPL
Copyright: (C) 2005 The University of Texas at Austin, http://www.utexas.edu $
LOC: 195
Project Info
FarCry CMS - Core(farcry_core)
Server: cvsdude
Type: svn
...core\trunk\packages\farcry\
   alterType.cfc
   audit.cfc
   cache.cfc
   category.cfc
   config.cfc
   email.cfc
   file.cfc
   form.cfc
   formtools.cfc
   fu.cfc
   genericAdmin.cfc
   geoLocator.cfc
   gregorianCalendar.cfc
   i18nUtil.cfc
   image.cfc
   imageUtilities.cfc
   javaRB.cfc
   jtidy.cfc
   locking.cfc
   objectadmin.cfc
   plpUtilities.cfc
   PrototypeTree.cfc
   rbJava.cfc
   reporting.cfc
   rss.cfc
   simpleImage.cfc
   stats.cfc
   sysinfo.cfc
   tmt_file_io.cfc
   tmt_zip.cfc
   tree.cfc
   typeadmin.cfc
   UrlUtility.cfc
   verity.cfc
   veritycf7.cfc
   versioning.cfc
   webtop.cfc
   WebtopMenu.cfc
   WebtopMenuitem.cfc
   WebtopRoot.cfc
   WebtopSection.cfc
   WebtopSubsection.cfc
   workflow.cfc
   zip.cfc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
<!--- {{{ jEdit Modes
:mode=coldfusion:
:collapseFolds=1:
:noTabs=true:
:tabSize=4:
:indentSize=4:
}}} --->
<!--- {{{
|| LEGAL ||
$Copyright: (C) 2005 The University of Texas at Austin, http://www.utexas.edu $
$License: Released Under the "Common Public License 1.0", http://www.opensource.com/licenses/cpl.php$

|| DESCRIPTION ||
$Description: Represents a webtop configuration, can merge with other webtop roots, and translate to and from xml. $

|| DEVELOPER ||
$Developer: Tyler Ham (tylerh@austin.utexas.edu)$
}}} --->

<cfcomponent displayname="Webtop Root"
  hint="Represents a webtop configuration, can merge with other webtop roots,
  and translate to and from xml.">
  
  <!--- about mergeType:
  webtop, section, subsection, menu, and menuitem are all nodes.
  The node being merged into/onto is referred to as node1.
  The node being merged is referred to as node2.
  
  If node1 has mergeType="none", 
    replaces and appends to node1 are not allowed.
  
  Otherwise, node1's mergeType is irrelevant.
  
  
  *** Possible mergeType's ***
    * replace
    * merge
    * mergeNoReplace
    * none
  
  
  *** Node2 Merge Types ***
    * replace
      - the entire node1 is trashed in favor of node2, as it is
    * merge
      - node1 takes on attributes/values of node2
      - if duplicate attributes exist, node2's values are used
      - children are merged normally (see below)
    * mergeNoReplace
      - node1 takes on attributes/values of node2
      - if duplicate attributes exist, node1's values are used
      - children are merged normally (see below)
    * none
      - if node2 has 'none' as the merge type, the
        default mergeType for the node is used
  
  
  *** Normal Children Merge ***
    - start with node1 children
    - for each child of node2:
       - if a node with a matching 'id' attribute value exists in node1:
          * merge the two children (recurse these comments with these two
            child nodes as node1 and node2)
       - otherwise, add the child of node2 to the list of children of node1
  
  
  *** Default mergeTypes ***
    * NODE          MERGETYPE
    ----------------------------
    * webtop        merge
    * section       merge
    * subsection    merge
    * menu          merge
    * menuitem      merge
    
  
  --->
  
  <cfset this.isInitialized = "false">
  <cfset this.stAttributes = StructNew()>
  <cfset this.aSections = ArrayNew(1)>
  
  <!--- default mergeType of a webtop is 'merge' --->
  <!--- other possible values: 'mergeNoReplace', 'replace', 'none' --->
  <!--- see above for more info on mergeTypes --->
  <cfset this.stAttributes.mergeType = "merge">
  
<!--- {{{ PUBLIC functions --->

<!--- {{{ public setPolicyGroup(policyGroupID) --->
<cffunction name="setPolicyGroup" access="public" output="no"
  hint="sets isAllowed attributes on each node if it allows access
  to the specified policy group">
  
  <cfargument name="policyGroupID" type="numeric" required="yes"
    hint="ID of the policy group to mark allowed nodes for">
  
  <cfargument name="overrideAllowed" type="boolean" default="false"
    hint="if true, a parent node that is disallowed will cause all children
    nodes to be disallowed, regardless of the permissions">
  
  <cfset var checkPermission = "">
  <cfset var i = "">
  
  <!--- first, get permissions - we'll need to pass them down the chain --->
  <cfset var permissions = getPermissions()>
  
  <!--- set isAllowed for the root node --->
  <cfif StructKeyExists(this.stAttributes, "permission")>
    <!--- check that any required permission on this node is allowed by the policy group --->
    <cfquery name="checkPermission" dbtype="query">
      SELECT *
      FROM permissions
      WHERE PolicyGroupID = <cfqueryparam value="#arguments.policyGroupID#" cfsqltype="cf_sql_numeric">
        AND PermissionName = <cfqueryparam value="#this.stAttributes.permission#" cfsqltype="cf_sql_varchar">
        AND Allowed = 1
    </cfquery>
    
    <cfif checkPermission.RecordCount>
      <cfset this.stAttributes.isAllowed = "true">
    <cfelse>
      <cfset this.stAttributes.isAllowed = "false">
    </cfif>
    
  <cfelse>
    <cfset this.stAttributes.isAllowed = "true">  <!--- allow by default --->
    
  </cfif>
  
  <!--- set policy group on children --->
  <cfloop index="i" from="1" to="#ArrayLen(this.aSections)#">
    <cfset this.aSections[i].setPolicyGroup(arguments.policyGroupID, permissions, arguments.overrideAllowed, this.stAttributes.isAllowed)>
  </cfloop>
  
</cffunction>
<!--- }}} public setPolicyGroup(policyGroupID) --->

<!--- {{{ public transformLabels() --->
<cffunction name="transformLabels" access="public" output="no"
  hint="transforms the label attributes (if any) of nodes
  depending on the labelType attribute (evaluate, expression, text)">
  
  <cfset var i = "">
  
  <!--- transform labels on children --->
  <cfloop index="i" from="1" to="#ArrayLen(this.aSections)#">
    <cfset this.aSections[i].transformLabels()>
  </cfloop>
  
</cffunction>
<!--- }}} public transformLabels() --->

<!--- {{{ public init(WebtopXmlDoc) --->
<cffunction name="init" access="public" output="no" returnType="WebtopRoot"
  hint="initializes this WebtopRoot with data from the given XmlDoc from a webtop xml file.">
  
  <cfargument name="WebtopXmlDoc" required="true"
    hint="webtop XmlDoc">
  
  <cfset var root = "">
  
  <!--- if anything is bad, simply return this --->
  <!--- isInitialized is still false, so getXml will --->
  <!--- just return empty string --->
  
  <!--- make sure the argument is an xml doc --->
  <cfif not isXmlDoc(arguments.WebtopXmlDoc)>
    <cfreturn this>
  </cfif>
  
  <!--- get Xmlroot --->
  <cfset root = arguments.WebtopXmlDoc.XmlRoot>
  
  <!--- make sure XmlName is 'webtop' --->
  <cfif not root.XmlName is "webtop">
    <cfreturn this>
  </cfif>
  
  <!--- ok, everything SEEMS ok, lets get the attributes --->
  <cfloop index="attrib" list="#StructKeyList(root.XmlAttributes)#">
    <cfset this.stAttributes[attrib] = root.XmlAttributes[attrib]>
  </cfloop>
  
  <!--- get the xml children --->
  <cfloop index="i" from="1" to="#ArrayLen(root.XmlChildren)#">
    <cfinvoke component="WebtopSection" method="init" returnVariable="newChild">
      <cfinvokeargument name="SectionXmlElement" value="#root.XmlChildren[i]#">
    </cfinvoke>
    <cfset ArrayAppend(this.aSections, newChild)>
  </cfloop>
  
  <!--- we are officially initialized, now getXml will work --->
  <cfset this.isInitialized = "true">
  
  <cfreturn this>
</cffunction>
<!--- }}} public init(WebtopXmlDoc) --->


<!--- {{{ public getXml() --->
<cffunction name="getXml" access="public" output="no" returnType="string"
  hint="returns xml of this webtop element as a string">
  
  <cfset var sOutput = "">
  <cfset var i = "">
  
  <!--- if we were not initialized with a proper WebtopXmlDoc, --->
  <!--- just return empty string --->
  <!--- this ought to do the least amount of harm --->
  <cfif not this.isInitialized>
    <cfreturn sOutput>
  </cfif>
  
  <!--- this call takes the struct and returns a string that looks like --->
  <!--- 'key="value" key="value" ...' --->
  <cfset sOutput = toAttributeString(this.stAttributes)>
  <cfset sOutput = "<webtop " & sOutput & " >">
  
  <!--- add the children --->
  <cfloop index="i" from="1" to="#ArrayLen(this.aSections)#">
    <cfset sOutput = sOutput & " " & this.aSections[i].getXml()>
  </cfloop>
  
  <!--- add the close tag --->
  <cfset sOutput = sOutput & " </webtop>">
  
  <cfreturn sOutput>
</cffunction>
<!--- }}} public getXml() --->


<!--- {{{ public mergeRoot(WebtopRoot root2) --->
<cffunction name="mergeRoot" access="public" output="no" returnType="void"
  hint="merges the given root2 onto this root, following any specified
  mergeType rules.  See WebtopRoot.cfc for more information about mergeType.
  Assuming root1 and root2 match.">
  
  <cfargument name="root2" type="WebtopRoot" required="true"
    hint="root to merge into this one">
  
  <!--- comment note: root1 means THIS --->
  
  <!--- if mergeType='none' on root1, it cannot be replaced or merged --->
  <cfif this.stAttributes.mergeType is "none">
    <cfreturn>
  </cfif>
  
  <cfswitch expression="#arguments.root2.stAttributes.mergeType#">
    <cfcase value="replace">
      <!--- replace ALL data about root1 with that of root2 --->
      <!--- ?? should we maintain the same mergeType, though?? -TH --->
      <cfset this.stAttributes = arguments.root2.stAttributes>
      <cfset this.aSections = arguments.root2.aSections>
    </cfcase>
    
    <cfcase value="merge">
      <!--- append root2.stAttributes to root1.stAttributes --->
      <!--- replace if duplicate keys --->
      <!--- normal merge/replace operation on children --->
      <cfset StructAppend(this.stAttributes, arguments.root2.stAttributes, "yes")>
      <cfset mergeChildren(arguments.root2)>
    </cfcase>
    
    <cfcase value="mergeNoReplace">
      <!--- append root2.stAttributes to root1.stAttributes --->
      <!--- do not replace duplicate keys --->
      <!--- normal merge/replace operation on children --->
      <cfset StructAppend(this.stAttributes, arguments.root2.stAttributes, "no")>
      <cfset mergeChildren(arguments.root2)>
    </cfcase>
    
    <cfdefaultcase> <!--- this will catch "none" values --->
      <!--- what should we do with strange mergeTypes? or "none"s? --->
      <!--- (remember, root1.id = root2.id - we assume this in here) --->
      <!--- How about "merge" as default for sections? -TH --->
      <cfset StructAppend(this.stAttributes, arguments.root2.stAttributes, "yes")>
      <cfset mergeChildren(arguments.root2)>
    </cfdefaultcase>
  </cfswitch>
  
</cffunction>
<!--- }}} public mergeRoot(WebtopRoot root2) --->


<!--- {{{ public getXmlDoc() --->
<cffunction name="getXmlDoc" access="public" output="no"
  hint="returns xmlDoc of this webtop's xml. 
  Convenience function, just parses getXml().">
  
  <cfreturn XmlParse(getXml())>
</cffunction>
<!--- }}} public getXmlDoc() --->



<!--- {{{ public toAttributeString(Struct stAttributes) --->
<cffunction name="toAttributeString" access="public" output="no" returnType="string"
  hint="converts a struct into a space-separated string of key/value pairs like
  'key=""value"" key=""value"" ...'">
  
  <cfargument name="stAttributes" type="Struct" required="true"
    hint="struct to convert to a string">
  
  <cfset var sOutput = "">
  <cfset var attrib = "">
  
  <cfloop index="attrib" list="#StructKeyList(arguments.stAttributes)#">
    <!--- XmlFormat makes the following characters safe for use in xml: 
          * Greater than symbol ( > )
          * Less than symbol ( < )
          * Single quotation mark ( ' )
          * Double quotation mark ( " )
          * Ambersand symbol ( & ) --->
    <cfset sOutput = sOutput & attrib & "=""" & XmlFormat(arguments.stAttributes[attrib]) & """ ">
  </cfloop>
  
  <!--- we might have ended up with a trailing space, remove it --->
  <cfif Right(sOutput, 1) is " ">
    <cfset sOutput = Left(sOutput, Len(sOutput)-1)>
  </cfif>
  
  <cfreturn sOutput>
</cffunction>
<!--- }}} public toAttributeString(Struct stAttribs) --->

<!--- }}} PUBLIC functions --->



<!--- {{{ PRIVATE functions --->

<!--- {{{ private mergeChildren(WebtopRoot root2) --->
<cffunction name="mergeChildren" access="private" output="no" returnType="void"
  hint="merges the children of root2 into the children of this root,
  following any specified mergeType rules.  See WebtopRoot.cfc for more information
  about mergeType.">
  
  <cfargument name="root2" type="WebtopRoot" required="true"
    hint="root whose children to merge with this one">
  
  <cfset var i = "">
  
  <!--- comment note: root1 means THIS --->
  
  <!--- loop through and merge each child (passing the buck again!) --->
  <cfloop index="i" from="1" to="#ArrayLen(arguments.root2.aSections)#">
    <cfset mergeChild(arguments.root2.aSections[i])>
  </cfloop>
  
</cffunction>
<!--- }}} private mergeChildren(WebtopRoot root2) --->


<!--- {{{ private mergeChild(WebtopSection child) --->
<cffunction name="mergeChild" access="private" output="no" returnType="void"
  hint="merges the child into aSections">
  
  <cfargument name="child" type="WebtopSection" required="true"
    hint="section to merge into this root's children">
  
  <cfset var i = "">
  <cfset var matchFound = "false">
  
  <!--- we must have an id to match, otherwise, no point in looking --->
  <cfif StructKeyExists(arguments.child.stAttributes, "id")>
    <!--- does the same child exist in this menu? --->
    <!--- ID will match, if so --->
    <cfloop index="i" from="1" to="#ArrayLen(this.aSections)#">
      <!--- id attribute must be present and must match --->
      <cfif StructKeyExists(this.aSections[i].stAttributes, "id")
        and this.aSections[i].stAttributes.id is arguments.child.stAttributes.id>
        
        <!--- set matchFound=true so we don't append the child later --->
        <cfset matchFound = "true">
        
        <!--- they match, so merge them --->
        <cfset this.aSections[i].mergeSection(arguments.child)>
        
        <!--- no need to keep looping --->
        <cfbreak>
      </cfif>
    </cfloop>
    
  </cfif>
  
  <cfif not matchFound>
    <!--- a match was not found, so we should append the menuitem --->
    <cfset ArrayAppend(this.aSections, arguments.child)>
  </cfif>
  
</cffunction>
<!--- }}} private mergeChild(WebtopSection child) --->


<!--- {{{ private getPermissions() --->
<cffunction name="getPermissions" access="private" output="no" returnType="query"
  hint="returns a query mapping policy groups and their permissions"
  hintReturnQuery="PolicyGroupID,PolicyGroupName,PermissionID,PermissionName,Allowed">
  
  <cfset var qReturn = QueryNew("PolicyGroupID,PolicyGroupName,PermissionID,PermissionName,Allowed")>
  <cfset var oAuthorisation = request.dmSec.oAuthorisation>
  <cfset var stObjectPermissions = oAuthorisation.getObjectPermission(reference="policyGroup",bUseCache=0)>
  <cfset var policyGroupID = "">
  <cfset var permissionID = "">
  <cfset var pg = "">
  <cfset var perm = "">
  <cfset var allowed = 1>
  
  <cfloop index="policyGroupID" list="#StructKeyList(stObjectPermissions)#">
    <cfset pg = oAuthorisation.getPolicyGroup(policyGroupID=policyGroupID)>
    
    <cfloop index="permissionID" list="#StructKeyList(stObjectPermissions[policyGroupID])#">
      <cfset perm = oAuthorisation.getPermission(permissionID=permissionID)>
      <cfset allowed = 1>
      <cfif stObjectPermissions[policyGroupID][permissionID].a eq -1
         or stObjectPermissions[policyGroupID][permissionID].a eq 0>
        <cfset allowed = 0>
      </cfif>
      
      <cfset QueryAddRow(qReturn)>
      <cfset QuerySetCell(qReturn, "PolicyGroupID", policyGroupID)>
      <cfset QuerySetCell(qReturn, "PolicyGroupName", pg.PolicyGroupName)>
      <cfset QuerySetCell(qReturn, "PermissionID", permissionID)>
      <cfset QuerySetCell(qReturn, "PermissionName", perm.PermissionName)>
      <cfset QuerySetCell(qReturn, "Allowed", allowed)>
    </cfloop>
    
  </cfloop>
  
  <cfreturn qReturn>
</cffunction>
<!--- }}} private getPermissions() --->

<!--- }}} PRIVATE functions --->


</cfcomponent>

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us