iris-pex-embedded-python 3.5.5b4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. grongier/__init__.py +0 -0
  2. grongier/cls/Grongier/PEX/BusinessOperation.cls +8 -0
  3. grongier/cls/Grongier/PEX/BusinessProcess.cls +13 -0
  4. grongier/cls/Grongier/PEX/BusinessService.cls +8 -0
  5. grongier/cls/Grongier/PEX/Common.cls +10 -0
  6. grongier/cls/Grongier/PEX/Director.cls +10 -0
  7. grongier/cls/Grongier/PEX/Duplex/Operation.cls +4 -0
  8. grongier/cls/Grongier/PEX/Duplex/Process.cls +13 -0
  9. grongier/cls/Grongier/PEX/Duplex/Service.cls +4 -0
  10. grongier/cls/Grongier/PEX/InboundAdapter.cls +8 -0
  11. grongier/cls/Grongier/PEX/Message.cls +13 -0
  12. grongier/cls/Grongier/PEX/OutboundAdapter.cls +8 -0
  13. grongier/cls/Grongier/PEX/PickleMessage.cls +13 -0
  14. grongier/cls/Grongier/PEX/PrivateSession/Duplex.cls +8 -0
  15. grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls +14 -0
  16. grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls +14 -0
  17. grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls +14 -0
  18. grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls +14 -0
  19. grongier/cls/Grongier/PEX/Test.cls +10 -0
  20. grongier/cls/Grongier/PEX/Utils.cls +10 -0
  21. grongier/cls/Grongier/Service/WSGI.cls +4 -0
  22. grongier/pex/__init__.py +24 -0
  23. grongier/pex/__main__.py +4 -0
  24. grongier/pex/_business_host.py +1 -0
  25. grongier/pex/_cli.py +4 -0
  26. grongier/pex/_common.py +1 -0
  27. grongier/pex/_director.py +1 -0
  28. grongier/pex/_utils.py +1 -0
  29. grongier/pex/wsgi/handlers.py +104 -0
  30. iop/__init__.py +25 -0
  31. iop/__main__.py +4 -0
  32. iop/_async_request.py +67 -0
  33. iop/_business_host.py +256 -0
  34. iop/_business_operation.py +75 -0
  35. iop/_business_process.py +224 -0
  36. iop/_business_service.py +63 -0
  37. iop/_cli.py +247 -0
  38. iop/_common.py +334 -0
  39. iop/_debugpy.py +187 -0
  40. iop/_decorators.py +49 -0
  41. iop/_director.py +301 -0
  42. iop/_dispatch.py +136 -0
  43. iop/_generator_request.py +30 -0
  44. iop/_inbound_adapter.py +34 -0
  45. iop/_iris.py +8 -0
  46. iop/_log_manager.py +100 -0
  47. iop/_message.py +40 -0
  48. iop/_message_validator.py +49 -0
  49. iop/_outbound_adapter.py +23 -0
  50. iop/_private_session_duplex.py +103 -0
  51. iop/_private_session_process.py +41 -0
  52. iop/_remote.py +91 -0
  53. iop/_serialization.py +199 -0
  54. iop/_utils.py +671 -0
  55. iop/cls/IOP/BusinessOperation.cls +35 -0
  56. iop/cls/IOP/BusinessProcess.cls +156 -0
  57. iop/cls/IOP/BusinessService.cls +40 -0
  58. iop/cls/IOP/Common.cls +569 -0
  59. iop/cls/IOP/Director.cls +70 -0
  60. iop/cls/IOP/Duplex/Operation.cls +29 -0
  61. iop/cls/IOP/Duplex/Process.cls +229 -0
  62. iop/cls/IOP/Duplex/Service.cls +9 -0
  63. iop/cls/IOP/Generator/Message/Ack.cls +31 -0
  64. iop/cls/IOP/Generator/Message/Poll.cls +31 -0
  65. iop/cls/IOP/Generator/Message/Start.cls +15 -0
  66. iop/cls/IOP/Generator/Message/StartPickle.cls +15 -0
  67. iop/cls/IOP/Generator/Message/Stop.cls +32 -0
  68. iop/cls/IOP/InboundAdapter.cls +22 -0
  69. iop/cls/IOP/Message/JSONSchema.cls +125 -0
  70. iop/cls/IOP/Message.cls +754 -0
  71. iop/cls/IOP/OutboundAdapter.cls +36 -0
  72. iop/cls/IOP/PickleMessage.cls +58 -0
  73. iop/cls/IOP/PrivateSession/Duplex.cls +260 -0
  74. iop/cls/IOP/PrivateSession/Message/Ack.cls +32 -0
  75. iop/cls/IOP/PrivateSession/Message/Poll.cls +32 -0
  76. iop/cls/IOP/PrivateSession/Message/Start.cls +31 -0
  77. iop/cls/IOP/PrivateSession/Message/Stop.cls +48 -0
  78. iop/cls/IOP/Projection.cls +49 -0
  79. iop/cls/IOP/Service/Remote/Handler.cls +30 -0
  80. iop/cls/IOP/Service/Remote/Rest/v1.cls +97 -0
  81. iop/cls/IOP/Service/WSGI.cls +310 -0
  82. iop/cls/IOP/Test.cls +85 -0
  83. iop/cls/IOP/Utils.cls +503 -0
  84. iop/cls/IOP/Wrapper.cls +58 -0
  85. iop/wsgi/handlers.py +104 -0
  86. iris_pex_embedded_python-3.5.5b4.dist-info/METADATA +91 -0
  87. iris_pex_embedded_python-3.5.5b4.dist-info/RECORD +91 -0
  88. iris_pex_embedded_python-3.5.5b4.dist-info/WHEEL +5 -0
  89. iris_pex_embedded_python-3.5.5b4.dist-info/entry_points.txt +2 -0
  90. iris_pex_embedded_python-3.5.5b4.dist-info/licenses/LICENSE +21 -0
  91. iris_pex_embedded_python-3.5.5b4.dist-info/top_level.txt +2 -0
@@ -0,0 +1,754 @@
1
+ Class IOP.Message Extends (Ens.MessageBody, %CSP.Page, Ens.VDoc.Interface)
2
+ {
3
+
4
+ Parameter DOCCLASSNAME = "JSON Document";
5
+
6
+ Parameter DOCCLASSFULLNAME = "JSON Virtual Document";
7
+
8
+ Parameter DOCSHORTNAME = "JSON";
9
+
10
+ Parameter BUFFER = 1000000;
11
+
12
+ Property buffer As %String(MAXLEN = "") [ Calculated, Transient ];
13
+
14
+ Property classname As %String(MAXLEN = "");
15
+
16
+ Property jsonObject As %DynamicObject(XMLPROJECTION = "None");
17
+
18
+ Property json As %String(MAXLEN = "");
19
+
20
+ Property jsonStream As %Stream.GlobalCharacter [ Internal, Private ];
21
+
22
+ Property jsonString As %String(MAXLEN = 1000000) [ Internal, Private ];
23
+
24
+ Property jstr As %Stream.GlobalCharacter [ Internal, Private ];
25
+
26
+ // for retrocompatibility
27
+
28
+ Property type As %String(MAXLEN = 6) [ ReadOnly ];
29
+
30
+ /// Gets the next index in an array
31
+ Method GetNextIndex(
32
+ pPath As %String,
33
+ pIndex As %String,
34
+ ByRef pStatus As %Status = {$$$OK}) As %String
35
+ {
36
+ Set f=$F(pPath,"()") If 'f Set pStatus=$$$ERROR($$$EnsErrGeneral,"Can't iterate on no-array type '"_pPath_"'") Quit ""
37
+ if pIndex="" Set pIndex=0
38
+ Set tValue = ..GetValueAt($EXTRACT(pPath, 1, $LENGTH(pPath)-2))
39
+ Set builtins = ##class(%SYS.Python).Builtins()
40
+ if pIndex>=builtins.len(tValue) Quit ""
41
+ Quit pIndex+1
42
+ }
43
+
44
+ Method GetValueAt(
45
+ pPropertyPath As %String = "",
46
+ pFormat As %String,
47
+ Output pStatus As %Status,
48
+ pDummy As %Boolean) As %String
49
+ {
50
+ Set pStatus = $$$OK
51
+ Try {
52
+ // Handle standard path queries
53
+ If pPropertyPath = "" Return ""
54
+
55
+ // pPropertyPath is formatted as :
56
+ // 1. "property1.property2.property3" for nested properties
57
+ // 2. "property1()" for all elements of an array or property1(*)
58
+ // 3. "property1(index).property2" for nested properties within an array
59
+ // 4. "property1(index)" for a specific element of an array
60
+
61
+ // Convert pPropertyPath to a a jsonpath
62
+ Set tPath = ..ConvertPath(pPropertyPath)
63
+
64
+ Set pyjson = ##class(%SYS.Python).Import("json")
65
+ Set jp = ##class(%SYS.Python).Import("jsonpath_ng")
66
+ Set builtins = ##class(%SYS.Python).Builtins()
67
+
68
+ Set tJSON = pyjson.loads(..json)
69
+ Set parser = jp.parse(tPath)
70
+ Set matches = parser.find(tJSON)
71
+
72
+ Set tResult = ""
73
+ // Return the first match
74
+ if matches."__len__"() = 1 {
75
+ Set match = matches."__getitem__"(0)
76
+ Set tResult = match."value"
77
+ }
78
+ ElseIf matches."__len__"() > 1 {
79
+ Set tResult = builtins.list()
80
+ For i=0:1:matches."__len__"()-1 {
81
+ Set match = matches."__getitem__"(i)
82
+ Do tResult.append(match."value")
83
+ }
84
+ }
85
+
86
+ Return tResult
87
+
88
+ } Catch ex {
89
+ Set pStatus = ex.AsStatus()
90
+ Return ""
91
+ }
92
+ }
93
+
94
+ ClassMethod ConvertPath(pPropertyPath As %String) As %String
95
+ {
96
+ // Convert pPropertyPath to a jsonpath just by replacing
97
+ // - '()' with '[*]'
98
+ // - '(index)' with '[index]'
99
+ // - '(' with '[' and ')' with ']'
100
+ // - if index is an integer, replace it with [index-1]
101
+ Set tPath = pPropertyPath
102
+ Set tPath = $Replace(tPath, "()", "[*]")
103
+ Set tPath = $Replace(tPath, "(", "[")
104
+ Set tPath = $Replace(tPath, ")", "]")
105
+ // Process each [] occurrence in the path
106
+ Set tPath = ..ProcessBrackets(tPath)
107
+
108
+ Return tPath
109
+ }
110
+
111
+ ClassMethod ProcessBrackets(pPath As %String) As %String
112
+ {
113
+ Set tPath = pPath
114
+ Set start = $Find(tPath, "[")
115
+ While start {
116
+ Set end = $Find(tPath, "]", start)
117
+ If 'end Quit // No matching closing bracket
118
+
119
+ // Extract the index between [ and ]
120
+ Set tIndex = $Extract(tPath, start, end-2)
121
+
122
+ // If index is numeric, decrease by 1 (0-based indexing)
123
+ If +tIndex {
124
+ Set newPath = $Extract(tPath, 1, start-1)
125
+ Set newPath = newPath _ (tIndex-1)
126
+ Set newPath = newPath _ $Extract(tPath, end-1, *)
127
+ Set tPath = newPath
128
+ }
129
+
130
+ // Move past this [] pair for next iteration
131
+ Set start = $Find(tPath, "[", end)
132
+ }
133
+ Return tPath
134
+ }
135
+
136
+ Method CopyValues(
137
+ pSource As Ens.VDoc.Interface,
138
+ pSourcePath As %String,
139
+ pTargetPath As %String,
140
+ pAction As %String,
141
+ pKey As %String,
142
+ pEmptyFieldAsNull As %Boolean = 0,
143
+ pIgnoreMissingSource As %Boolean = 0,
144
+ pGenerateEmptySegments As %Boolean = 0) As %Status
145
+ {
146
+ Set tSC = $$$OK
147
+ Try {
148
+ // Get source value
149
+ Set tValue = pSource.GetValueAt(pSourcePath, "String", .tSC, 0)
150
+ Return:$$$ISERR(tSC) tSC
151
+
152
+ // Set target value
153
+ Set tSC = ..SetValueAt(tValue, pTargetPath, pAction, pKey)
154
+ } Catch ex {
155
+ Set tSC = ex.AsStatus()
156
+ }
157
+ Return tSC
158
+ }
159
+
160
+ /// Sets a value at the specified property path in the JSON document
161
+ /// @param pValue Value to set
162
+ /// @param pPropertyPath Path to the property (e.g. "property1.property2" or "array()")
163
+ /// @param pAction Action to perform ("set", "append", "remove", "insert")
164
+ /// @param pKey Optional key for specialized operations, required for insert
165
+ /// @returns %Status
166
+ Method SetValueAt(
167
+ pValue As %String = "",
168
+ pPropertyPath As %String = "",
169
+ pAction As %String = "set",
170
+ pKey As %String = "") As %Status
171
+ {
172
+ Set tSC = $$$OK
173
+ Try {
174
+ // Validate input parameters
175
+ If pPropertyPath = "" Return $$$ERROR($$$GeneralError, "Property path cannot be empty")
176
+ If '$LISTFIND($LISTBUILD("set","append","remove","insert"), pAction) Return $$$ERROR($$$GeneralError, "Invalid action: "_pAction)
177
+ If (pAction = "insert") && (pKey = "") Return $$$ERROR($$$GeneralError, "Key is required for insert action")
178
+
179
+ // Initialize Python objects
180
+ Set pyjson = ##class(%SYS.Python).Import("json")
181
+ Set jp = ##class(%SYS.Python).Import("jsonpath_ng")
182
+ Set builtins = ##class(%SYS.Python).Builtins()
183
+
184
+ // Handle append operations
185
+ Set tAppend = (pAction = "append")
186
+ If tAppend, $EXTRACT(pPropertyPath, *-1, *) = "()" {
187
+ Set pPropertyPath = $EXTRACT(pPropertyPath, 1, *-2)
188
+ }
189
+
190
+ // Initialize empty JSON if needed
191
+ Set:..json="" ..json = "{}"
192
+
193
+ // Parse JSON and prepare path
194
+ Set tJSON = pyjson.loads(..json)
195
+ Set tPath = ..ConvertPath(pPropertyPath)
196
+ Set parser = jp.parse(tPath)
197
+
198
+ If pAction = "set" {
199
+ // Simple set operation
200
+ Set tJSON = parser."update_or_create"(tJSON, pValue)
201
+ }
202
+ ElseIf pAction = "remove" {
203
+ // Remove operation
204
+ Set matches = parser.find(tJSON)
205
+ If matches."__len__"() > 0 {
206
+ // Not yet implemented
207
+ Set tSC = $$$ERROR($$$GeneralError, "Remove operation not yet implemented")
208
+ }
209
+ }
210
+ ElseIf pAction = "insert" {
211
+ // Handle dictionary insert/update
212
+ Set matches = parser.find(tJSON)
213
+ If matches."__len__"() = 0 {
214
+ // Create new dictionary if path doesn't exist
215
+ Set tDict = builtins.dict()
216
+ Do tDict."__setitem__"(pKey, pValue)
217
+ Set tJSON = parser."update_or_create"(tJSON, tDict)
218
+ }
219
+ Else {
220
+ // Update existing dictionary
221
+ Set tDict = matches."__getitem__"(0)."value"
222
+ Do tDict."__setitem__"(pKey, pValue)
223
+ Set tJSON = parser."update"(tJSON, tDict)
224
+ }
225
+ }
226
+ ElseIf tAppend {
227
+ // Handle append operation
228
+ Set tFindValue = parser."find"(tJSON)
229
+ If tFindValue."__len__"() = 0 {
230
+ // Create new array if path doesn't exist
231
+ Set:(tAppend) tValue = builtins.list()
232
+ Do:tAppend tValue.append(pValue)
233
+ Set tJSON = parser."update_or_create"(tJSON, $Select(tAppend: tValue, 1: pValue))
234
+ }
235
+ Else {
236
+ // Append to existing array
237
+ Do tFindValue."__getitem__"(0)."value".append(pValue)
238
+ Set tJSON = parser."update"(tJSON, tFindValue."__getitem__"(0)."value")
239
+ }
240
+ }
241
+
242
+ // Update JSON storage
243
+ Set ..json = pyjson.dumps(tJSON)
244
+ Set ..classname = ..DocType
245
+
246
+ }
247
+ Catch ex {
248
+ Set tSC = ex.AsStatus()
249
+ // Log error details
250
+ $$$LOGWARNING("Error in SetValueAt: "_$System.Status.GetErrorText(tSC))
251
+ }
252
+
253
+ Return tSC
254
+ }
255
+
256
+ Method IsValid() As %Status
257
+ {
258
+ Return $$$OK
259
+ }
260
+
261
+ Method Validate(pValidationSpec As %String = "") As %Status
262
+ {
263
+ If ..DocType = "" Return $$$ERROR($$$GeneralError, "No DocType specified")
264
+
265
+ // Validate against stored schema
266
+ Return ##class(IOP.Message.JSONSchema).ValidateJSON(tJSON, ..DocTypeCategory, ..DocTypeName)
267
+ }
268
+
269
+ Method ParentMany(Output pParentsList) As %Integer
270
+ {
271
+ Return 0
272
+ }
273
+
274
+ /// Returns a list of available DocTypes by querying the JSONSchema storage.
275
+ Query EnumerateDocTypes(
276
+ Category As %String = "",
277
+ IncludeBase As %Boolean = 0) As %Query(CONTAINID = 0, ROWSPEC = "Type:%String")
278
+ {
279
+ }
280
+
281
+ ClassMethod EnumerateDocTypesExecute(
282
+ ByRef qHandle As %Binary,
283
+ pName As %String = "",
284
+ IncludeBase As %Boolean) As %Status
285
+ {
286
+ Kill qHandle
287
+ Set qHandle = 0
288
+ Set sql = "SELECT Name FROM IOP_Message.JSONSchema"
289
+ If pName '= "" {
290
+ Set sql = sql _ " WHERE Name = ?"
291
+ }
292
+
293
+ Set stmt = ##class(%SQL.Statement).%New()
294
+ Set tSC = stmt.%Prepare(sql)
295
+ Quit:$$$ISERR(tSC) tSC
296
+
297
+ If pName '= "" {
298
+ Set rs = stmt.%Execute(pName)
299
+ } Else {
300
+ Set rs = stmt.%Execute()
301
+ }
302
+ While rs.%Next() {
303
+ Set qHandle($I(qHandle)) = rs.%Get("Name")
304
+ }
305
+ set qHandle = 0
306
+ Quit $$$OK
307
+ }
308
+
309
+ ClassMethod EnumerateDocTypesFetch(
310
+ ByRef qHandle As %Binary,
311
+ ByRef qRow As %List,
312
+ ByRef AtEnd As %Integer = 0) As %Status
313
+ {
314
+ Set qHandle = $O(qHandle(qHandle))
315
+ If qHandle = "" {
316
+ Set qRow = "", AtEnd = 1
317
+ Quit $$$OK
318
+ }
319
+ Set qRow = $LB(qHandle(qHandle))
320
+ Quit $$$OK
321
+ }
322
+
323
+ ClassMethod EnumerateDocTypesClose(ByRef qHandle As %Binary) As %Status
324
+ {
325
+ Kill qHandle
326
+ Quit $$$OK
327
+ }
328
+
329
+ /// Returns a list of schema categories from the JSONSchema storage.
330
+ Query EnumerateTypeCategories(Standard As %String = "") As %Query(CONTAINID = 0, ROWSPEC = "Category:%String,Description:%String,IsStandard:%Boolean,Base:%String")
331
+ {
332
+ }
333
+
334
+ ClassMethod EnumerateTypeCategoriesExecute(
335
+ ByRef qHandle As %Binary,
336
+ pStandard As %String = "") As %Status
337
+ {
338
+ Kill qHandle
339
+ Set qHandle = 0
340
+ Set sql = "SELECT Category, Name FROM IOP_Message.JSONSchema"
341
+
342
+ Set stmt = ##class(%SQL.Statement).%New()
343
+ Set tSC = stmt.%Prepare(sql)
344
+ Quit:$$$ISERR(tSC) tSC
345
+
346
+ Set rs = stmt.%Execute()
347
+
348
+ While rs.%Next() {
349
+ Set category = rs.%Get(1)
350
+ // Format: Category, Description, IsStandard, Base
351
+ Set qHandle($I(qHandle)) = $LB(category, "JSON Schema category", "IsStandard", "Base")
352
+ }
353
+ Set qHandle = 0
354
+ Quit $$$OK
355
+ }
356
+
357
+ ClassMethod EnumerateTypeCategoriesFetch(
358
+ ByRef qHandle As %Binary,
359
+ ByRef Row As %List,
360
+ ByRef AtEnd As %Integer = 0) As %Status
361
+ {
362
+ Set qHandle = $O(qHandle(qHandle))
363
+ If qHandle = "" {
364
+ Set Row = "", AtEnd = 1
365
+ Quit $$$OK
366
+ }
367
+ Set Row = qHandle(qHandle)
368
+ Quit $$$OK
369
+ }
370
+
371
+ ClassMethod EnumerateTypeCategoriesClose(ByRef qHandle As %Binary) As %Status
372
+ {
373
+ Kill qHandle
374
+ Quit $$$OK
375
+ }
376
+
377
+ /// Returns array of properties that make up the <i>contents</i>
378
+ /// of this object.<br>
379
+ /// This method in implemented within the document class.<br>
380
+ /// The content array is in the form:<br>
381
+ /// pContents(n,"type")="%String"<br>
382
+ /// pContents(n,"name")="Field"<br>
383
+ /// pContents(n,"alias")=alias code<br>
384
+ /// If pContents(n) is non-zero then the property is a composite type with<br>
385
+ /// sub-properties. The sub-properties are indexed with a similar structure under<br>
386
+ /// pContents(n,m) where m is the index of the subtype property.<br>
387
+ ClassMethod GetContentArray(
388
+ Output pContents,
389
+ pMode As %String,
390
+ pDocType As %String = "MESSAGE",
391
+ pLevel As %Integer,
392
+ pIncludeBase As %Boolean = 0) As %Status
393
+ {
394
+ Set tSC = $$$OK
395
+ Try {
396
+ // Get schema structure
397
+ Set tName = pDocType
398
+ #; Set tName = $Piece(pDocType, ":", 2)
399
+
400
+ Set tSC = ##class(IOP.Message.JSONSchema).GetSchema(tName, .json)
401
+ If $$$ISERR(tSC) Return tSC
402
+ set schema = {}.%FromJSON(json)
403
+
404
+ $$$ThrowOnError(##class(IOP.Message).SchemaToContents(schema, .tContents))
405
+
406
+ Merge @pContents = tContents
407
+ }
408
+ Catch ex {
409
+ Set tSC = ex.AsStatus()
410
+ }
411
+ Return $$$OK
412
+ }
413
+
414
+ /// Convert a JSON schema structure into a contents array format
415
+ /// schema: Dynamic object containing the JSON schema
416
+ /// Output pContents: Array to store the contents structure
417
+ /// Returns: %Status
418
+ ClassMethod SchemaToContents(
419
+ schema As %DynamicObject,
420
+ Output pContents) As %Status
421
+ {
422
+ Set tSC = $$$OK
423
+ Try {
424
+ Set idx = 0
425
+ Do ..ProcessProperties(schema.properties, .idx, .pContents, schema)
426
+ }
427
+ Catch ex {
428
+ Set tSC = ex.AsStatus()
429
+ }
430
+ Return tSC
431
+ }
432
+
433
+ ClassMethod ProcessProperties(
434
+ properties As %DynamicObject,
435
+ ByRef idx As %Integer,
436
+ Output pContents,
437
+ schema As %DynamicObject) As %Status
438
+ {
439
+ Set iterator = properties.%GetIterator()
440
+ While iterator.%GetNext(.key, .value) {
441
+ Set idx = idx + 1
442
+ Do ..HandleProperty(value, .key, idx, .pContents, schema)
443
+ }
444
+ Return $$$OK
445
+ }
446
+
447
+ ClassMethod HandleProperty(
448
+ value As %DynamicObject,
449
+ ByRef key As %String,
450
+ idx As %Integer,
451
+ Output pContents,
452
+ schema As %DynamicObject)
453
+ {
454
+ Set type = value.type
455
+
456
+ If (type = "string") || (type = "number") || (type = "boolean") {
457
+ Do ..HandlePrimitiveType(type, idx, .pContents)
458
+ }
459
+ ElseIf type = "array" {
460
+ Do ..HandleArrayType(value, .key, idx, .pContents, schema)
461
+ }
462
+ ElseIf type = "object" {
463
+ Do ..HandleObjectType(value, idx, .pContents)
464
+ }
465
+ ElseIf $IsObject(value.allOf) {
466
+ Do ..HandleAllOfType(value, key, idx, .pContents, schema)
467
+ }
468
+ ElseIf value.%Get("$ref")'="" {
469
+ Set tDef = schema."$defs".%Get($Piece(value."$ref", "/", *))
470
+ Do ..HandleObjectType(tDef, idx, .pContents)
471
+ }
472
+ Else {
473
+ Set pContents(idx,"type") = type
474
+ }
475
+
476
+ If type = "array" Set key = key_"()"
477
+ Set pContents = idx
478
+ Set pContents(idx,"name") = key
479
+ Set pContents(idx,"alias") = key
480
+ }
481
+
482
+ ClassMethod HandlePrimitiveType(
483
+ type As %String,
484
+ idx As %Integer,
485
+ Output pContents)
486
+ {
487
+ Set pContents(idx,"type") = $Case(type,
488
+ "string": "%String",
489
+ "number": "%Numeric",
490
+ "boolean": "%Boolean")
491
+ }
492
+
493
+ ClassMethod HandleArrayType(
494
+ value As %DynamicObject,
495
+ ByRef key As %String,
496
+ idx As %Integer,
497
+ Output pContents,
498
+ schema As %DynamicObject)
499
+ {
500
+ Set pContents(idx,"type") = "()"
501
+ // Handle array as a Handle Property
502
+ Do ..HandleProperty(value.items, key, idx, .pContents, schema)
503
+ }
504
+
505
+ ClassMethod HandleObjectType(
506
+ value As %DynamicObject,
507
+ idx As %Integer,
508
+ Output pContents)
509
+ {
510
+ Set pContents(idx,"type") = "object"
511
+ If $IsObject(value.properties) {
512
+ Do ..SchemaToContents(value, .subContents)
513
+ Merge pContents(idx) = subContents
514
+ }
515
+ }
516
+
517
+ ClassMethod HandleAllOfType(
518
+ value As %DynamicObject,
519
+ key As %String,
520
+ idx As %Integer,
521
+ Output pContents,
522
+ schema As %DynamicObject)
523
+ {
524
+ Set pContents(idx) = 1 //TODO size of subContents
525
+ Set pContents(idx,"type") = "object"
526
+ Set pContents(idx,"name") = key
527
+ Set pContents(idx,"alias") = key
528
+
529
+ Set allOfIterator = value.allOf.%GetIterator()
530
+ While allOfIterator.%GetNext(.allOfKey, .allOfValue) {
531
+ If $IsObject(allOfValue."$ref") {
532
+ Do ..SchemaToContents(allOfValue."$ref", .subContents)
533
+ }
534
+ Else {
535
+ Set tDef = schema."$defs".%Get($Piece(allOfValue."$ref","/",*))
536
+ Do ..SchemaToContents(tDef, .subContents)
537
+ }
538
+ Merge pContents(idx) = subContents
539
+ }
540
+ }
541
+
542
+ Method bufferGet()
543
+ {
544
+ Quit ..#BUFFER
545
+ }
546
+
547
+ Method %OnNew(classname) As %Status [ Private, ServerOnly = 1 ]
548
+ {
549
+ set ..classname = $g(classname)
550
+ Quit $$$OK
551
+ }
552
+
553
+ Method jstrGet()
554
+ {
555
+ set rsp = $$$NULLOREF
556
+ // Get as stream no matter what
557
+ if ..type="String" {
558
+ Set rsp = ##class(%Stream.GlobalCharacter).%New()
559
+ Set sc = rsp.Write(..jsonString)
560
+ }
561
+ elseif ..type="Stream" {
562
+ set rsp = ..jsonStream
563
+ }
564
+ Quit rsp
565
+ }
566
+
567
+ Method jstrSet(pInput) As %Status
568
+ {
569
+ // Set as stream no matter what
570
+ set sc = ..jsonSet(pInput)
571
+ if $$$ISERR(sc) { Quit sc }
572
+ if ..type="String" {
573
+ set stream = ##class(%Stream.GlobalCharacter).%New()
574
+ Set sc = stream.Write(..jsonString)
575
+ set r%jsonStream = stream
576
+ set i%type = "Stream"
577
+ }
578
+ Quit sc
579
+ }
580
+
581
+ Method jsonGet()
582
+ {
583
+ Quit $Case(..type
584
+ , "String":..jsonString
585
+ , "Stream":..jsonStream
586
+ , :$$$NULLOREF)
587
+ }
588
+
589
+ Method jsonSet(pInput) As %Status
590
+ {
591
+ Set tOldStream=$Case(..type
592
+ , "String":..jsonString
593
+ , "Stream":..jsonStream
594
+ , :$$$NULLOREF)
595
+ Quit:tOldStream=pInput $$$OK
596
+
597
+ If ..type'="" {
598
+ Set:(..type="String") i%jsonString=""
599
+ Set:(..type="Stream") i%jsonStream=$$$NULLOREF
600
+ Set i%type = ""
601
+ }
602
+
603
+ If $ISOBJECT(pInput) {
604
+ if pInput.%Extends("%Stream.GlobalCharacter") {
605
+ Set r%jsonStream=pInput, i%type="Stream"
606
+ }
607
+ else {
608
+ Throw ##class(%Exception.General).%New("Invalid input type, must be a %Stream.GlobalCharacter or a %String")
609
+ }
610
+ }
611
+ Else {
612
+ if $LENGTH(pInput)>..#BUFFER {
613
+ // write in a stream
614
+ Set stream = ##class(%Stream.GlobalCharacter).%New()
615
+ for i=1:..#BUFFER:$LENGTH(pInput) {
616
+ Set sc = stream.Write($EXTRACT(pInput,i,(i+..#BUFFER-1)))
617
+ Quit:$$$ISERR(sc)
618
+ }
619
+ Set r%jsonStream=stream, i%type="Stream"
620
+ }
621
+ else {
622
+ Set i%jsonString=pInput, i%type="String"
623
+ }
624
+ }
625
+ }
626
+
627
+ Method GetObjectJson(ByRef atEnd)
628
+ {
629
+ set atEnd = 1
630
+ if ..type = "String" {
631
+ set json = ..jsonString
632
+ }
633
+ elseif ..type = "Stream" {
634
+ do ..jsonStream.Rewind()
635
+ set json = ..jsonStream.Read(..#BUFFER)
636
+ set atEnd = ..jsonStream.AtEnd
637
+ }
638
+ QUIT json
639
+ }
640
+
641
+ /// This method is called by the Management Portal to determine the content type that will be returned by the <method>%ShowContents</method> method.
642
+ /// The return value is a string containing an HTTP content type.
643
+ Method %GetContentType() As %String
644
+ {
645
+ Quit "text/html"
646
+ }
647
+
648
+ /// This method is called by the Management Portal to display a portion of the HEAD section of a message-specific content viewer.<br>
649
+ Method %ShowContentsHead(pZenOutput As %Boolean = 0)
650
+ {
651
+ &html<<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>>
652
+ &html<<script>var makeCompleteJSON=function(l,n){for(var r=["{","}","[","]",'"',"'"],t=function(l){for(var n=l.split(""),r=null,t=[],u=0;u<n.length;u++)char=n[u],"'"!=char&&'"'!=char||(null==r?r=char:r==char&&(r=null)),null==r&&":"==char&&t.push(u);return 1==t.length&&t[0]!=n.length-1},u=[],p=null,e=l.split(""),h="",o=-1,a=[],i=0;i<e.length;i++){if($.inArray(e[i],r)>-1){if(0==u.length&&("'"==e[i]||'"'==e[i]))return!1;'"'==p||"'"==p?p==e[i]&&(u.pop(),p=u[u.length-1]):"}"==e[i]&&"{"==p?(u.pop(),a.pop(),p=u[u.length-1],h="",o=-1):"]"==e[i]&&"["==p?(u.pop(),a.pop(),p=u[u.length-1]):(u.push(e[i]),"["==(p=e[i])&&a.push("array"),"{"==p&&(a.push("object"),o=i))}"object"==a[a.length-1]&&(h+=e[i])}if(!n&&o>-1){var s=function(l){for(var n=l.split(""),r=null,u=null,p=[],e=1;e<n.length;e++)"'"!=(r=n[e])&&'"'!=r||(null==u?u=r:u==r&&(u=null)),null==u&&","==r&&p.push(e);var h=[],o=1;for(e=0;e<p.length;e++)h.push($.trim(l.substring(o,p[e]))),o=p[e]+1;h.push($.trim(l.substring(o)));var a=h[h.length-1];return a.split(""),t(a)||h.pop(),"{"+h.join(",")}(h);return l=l.substring(0,o)+s,makeCompleteJSON(l,!0)}for(;u.length>0;)'"'==(p=u.pop())&&(l+='"'),"'"==p&&(l+="'"),"{"==p&&(l+="}"),"["==p&&(l+="]");return l};</script>>
653
+ &html<<script>!function(e){"use strict";var n=function(n){var a=e("<span />",{"class":"collapser",on:{click:function(){var n=e(this);n.toggleClass("collapsed");var a=n.parent().children(".block"),p=a.children("ul");n.hasClass("collapsed")?(p.hide(),a.children(".dots, .comments").show()):(p.show(),a.children(".dots, .comments").hide())}}});return n&&a.addClass("collapsed"),a},a=function(a,p){var t=e.extend({},{nl2br:!0},p),r=function(e){return e.toString()?e.toString().replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):""},s=function(n,a){return e("<span />",{"class":a,html:r(n)})},l=function(a,p){switch(e.type(a)){case"object":p||(p=0);var c=e("<span />",{"class":"block"}),d=Object.keys(a).length;if(!d)return c.append(s("{","b")).append(" ").append(s("}","b"));c.append(s("{","b"));var i=e("<ul />",{"class":"obj collapsible level"+p});return e.each(a,function(a,t){d--;var r=e("<li />").append(s('"',"q")).append(a).append(s('"',"q")).append(": ").append(l(t,p+1));-1===["object","array"].indexOf(e.type(t))||e.isEmptyObject(t)||r.prepend(n()),d>0&&r.append(","),i.append(r)}),c.append(i),c.append(s("...","dots")),c.append(s("}","b")),c.append(1===Object.keys(a).length?s("// 1 item","comments"):s("// "+Object.keys(a).length+" items","comments")),c;case"array":p||(p=0);var d=a.length,c=e("<span />",{"class":"block"});if(!d)return c.append(s("[","b")).append(" ").append(s("]","b"));c.append(s("[","b"));var i=e("<ul />",{"class":"obj collapsible level"+p});return e.each(a,function(a,t){d--;var r=e("<li />").append(l(t,p+1));-1===["object","array"].indexOf(e.type(t))||e.isEmptyObject(t)||r.prepend(n()),d>0&&r.append(","),i.append(r)}),c.append(i),c.append(s("...","dots")),c.append(s("]","b")),c.append(1===a.length?s("// 1 item","comments"):s("// "+a.length+" items","comments")),c;case"string":if(a=r(a),/^(http|https|file):\/\/[^\s]+$/i.test(a))return e("<span />").append(s('"',"q")).append(e("<a />",{href:a,text:a})).append(s('"',"q"));if(t.nl2br){var o=/\n/g;o.test(a)&&(a=(a+"").replace(o,"<br />"))}var u=e("<span />",{"class":"str"}).html(a);return e("<span />").append(s('"',"q")).append(u).append(s('"',"q"));case"number":return s(a.toString(),"num");case"undefined":return s("undefined","undef");case"null":return s("null","null");case"boolean":return s(a?"true":"false","bool")}};return l(a)};return e.fn.jsonView=function(n,p){var t=e(this);if(p=e.extend({},{nl2br:!0},p),"string"==typeof n)try{n=JSON.parse(n)}catch(r){}return t.append(e("<div />",{"class":"json-view"}).append(a(n,p))),t}}(jQuery);</script>>
654
+ &html<<style type="text/css">
655
+ .json-view{position:relative}
656
+ .json-view .collapser{width:20px;height:18px;display:block;position:absolute;left:-1.7em;top:-.2em;z-index:5;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD1JREFUeNpiYGBgOADE%2F3Hgw0DM4IRHgSsDFOzFInmMAQnY49ONzZRjDFiADT7dMLALiE8y4AGW6LoBAgwAuIkf%2F%2FB7O9sAAAAASUVORK5CYII%3D);background-repeat:no-repeat;background-position:center center;opacity:.5;cursor:pointer}
657
+ .json-view .collapsed{-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-khtml-transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}
658
+ .json-view .bl{display:block;padding-left:20px;margin-left:-20px;position:relative}
659
+ .json-view {font-family:Verdana,sans-serif; font-size: 0.8em;}
660
+ .json-view ul{list-style-type:none;padding-left:2em;border-left:1px dotted;margin:.3em}
661
+ .json-view ul li{position:relative;color:#012E55}
662
+ .json-view .comments,.json-view .dots{display:none;-moz-user-select:none;-ms-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}
663
+ .json-view .comments{padding-left:.8em;font-style:italic;color:#888}
664
+ .json-view .bool,.json-view .null,.json-view .num,.json-view .undef{font-weight:700;color:#1A01CC}
665
+ .json-view .str{color:#F79243}
666
+ </style>>
667
+ }
668
+
669
+ /// This method is called by the Management Portal to display a message-specific content viewer.<br>
670
+ /// This method displays its content by writing out to the current device.
671
+ /// The content should match the type returned by the <method>%GetContentType</method> method.<br>
672
+ Method %ShowContents(pZenOutput As %Boolean = 0)
673
+ {
674
+ set jsonObject = ..QuoteJS(..GetObjectJson(.atEnd))
675
+ set buffer = ..#BUFFER
676
+ if 'atEnd {
677
+ &html<<div>Warning JSON projection is not comptete, it's truncated, #(buffer)# charaters display</div>>
678
+ }
679
+ // https://github.com/bazh/jquery.json-view
680
+ &html<<div id="element">#(..classname)#</div>>
681
+ &html<<script>$(function() {$('#element').jsonView(makeCompleteJSON(#(jsonObject)#,false));});</script>>
682
+ }
683
+
684
+ ClassMethod %OnDelete(oid As %ObjectIdentity) As %Status [ Private ]
685
+ {
686
+ // Delete the property object references.
687
+ Set tSC = $$$OK
688
+ // Kill the global references in ^Ens.MessageBodyD(oid) and all its sub-nodes
689
+ Do ##class(Ens.MessageBody).%DeleteId(oid,.tSC)
690
+ Quit tSC
691
+ }
692
+
693
+ /// Callback/Trigger for SQL delete
694
+ Trigger OnDelete [ Event = DELETE ]
695
+ {
696
+ // Delete the property object references. {%%ID} holds the id of the record being deleted.
697
+ Set tID={%%ID}
698
+ Do ##class(Ens.MessageBody).%DeleteId(tID,.tSC)
699
+ Quit
700
+ }
701
+
702
+ Storage Default
703
+ {
704
+ <Data name="MessageDefaultData">
705
+ <Subscript>"Message"</Subscript>
706
+ <Value name="1">
707
+ <Value>classname</Value>
708
+ </Value>
709
+ <Value name="2">
710
+ <Value>json</Value>
711
+ </Value>
712
+ <Value name="3">
713
+ <Value>jstr</Value>
714
+ </Value>
715
+ <Value name="4">
716
+ <Value>jsonStream</Value>
717
+ </Value>
718
+ <Value name="5">
719
+ <Value>type</Value>
720
+ </Value>
721
+ <Value name="6">
722
+ <Value>jsonString</Value>
723
+ </Value>
724
+ <Value name="7">
725
+ <Value>DocType</Value>
726
+ </Value>
727
+ <Value name="8">
728
+ <Value>TimeCreated</Value>
729
+ </Value>
730
+ <Value name="9">
731
+ <Value>Source</Value>
732
+ </Value>
733
+ <Value name="10">
734
+ <Value>IsMutable</Value>
735
+ </Value>
736
+ <Value name="11">
737
+ <Value>OriginalDocId</Value>
738
+ </Value>
739
+ </Data>
740
+ <Data name="UserValues">
741
+ <Attribute>UserValues</Attribute>
742
+ <Structure>subnode</Structure>
743
+ <Subscript>"IOP.Message.UserValues"</Subscript>
744
+ </Data>
745
+ <Data name="jsonObject">
746
+ <Attribute>jsonObject</Attribute>
747
+ <Structure>node</Structure>
748
+ <Subscript>"IOP.Message.jsonObject"</Subscript>
749
+ </Data>
750
+ <DefaultData>MessageDefaultData</DefaultData>
751
+ <Type>%Storage.Persistent</Type>
752
+ }
753
+
754
+ }