├── .gitignore
├── Harness Projects
├── App.xojo_code
├── Build Automation.xojo_code
├── Examples
│ ├── Eddies.xojo_code
│ ├── Eddies
│ │ ├── Customer.xojo_code
│ │ ├── GetCustomer.xojo_code
│ │ └── GetCustomerList.xojo_code
│ ├── GetCatsMessage.xojo_code
│ └── SQLFormatter.xojo_code
├── MainMenuBar.xojo_menu
├── REST Harness.xojo_project
├── REST Harness.xojo_resources
└── Windows Folder
│ ├── WndCats.xojo_window
│ ├── WndEddies.xojo_window
│ ├── WndMain.xojo_window
│ └── WndSQLFormatter.xojo_window
├── LICENSE.md
├── README.md
└── REST Resources
├── M_REST.xojo_code
└── M_REST
├── ClassMeta.xojo_code
├── Options.xojo_code
├── PrivateMessage.xojo_code
├── PrivateOptions.xojo_code
├── PrivateSurrogate.xojo_code
├── RESTException.xojo_code
├── RESTMessageSurrogate_MTC.xojo_code
├── RESTMessage_MTC.xojo_code
└── TextProvider.xojo_code
/.gitignore:
--------------------------------------------------------------------------------
1 | *.xojo_uistate
2 | .vscode
3 |
--------------------------------------------------------------------------------
/Harness Projects/App.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Protected Class App
3 | Inherits Application
4 | #tag MenuHandler
5 | Function ExamplesCats() As Boolean Handles ExamplesCats.Action
6 | WndCats.Show
7 | Return True
8 |
9 | End Function
10 | #tag EndMenuHandler
11 |
12 | #tag MenuHandler
13 | Function ExamplesEddies() As Boolean Handles ExamplesEddies.Action
14 | WndEddies.Show
15 | Return True
16 |
17 | End Function
18 | #tag EndMenuHandler
19 |
20 | #tag MenuHandler
21 | Function ExamplesSQLFormatter() As Boolean Handles ExamplesSQLFormatter.Action
22 | WndSQLFormatter.Show
23 | Return True
24 |
25 | End Function
26 | #tag EndMenuHandler
27 |
28 |
29 | #tag Constant, Name = kEditClear, Type = String, Dynamic = False, Default = \"&Delete", Scope = Public
30 | #Tag Instance, Platform = Windows, Language = Default, Definition = \"&Delete"
31 | #Tag Instance, Platform = Linux, Language = Default, Definition = \"&Delete"
32 | #tag EndConstant
33 |
34 | #tag Constant, Name = kFileQuit, Type = String, Dynamic = False, Default = \"&Quit", Scope = Public
35 | #Tag Instance, Platform = Windows, Language = Default, Definition = \"E&xit"
36 | #tag EndConstant
37 |
38 | #tag Constant, Name = kFileQuitShortcut, Type = String, Dynamic = False, Default = \"", Scope = Public
39 | #Tag Instance, Platform = Mac OS, Language = Default, Definition = \"Cmd+Q"
40 | #Tag Instance, Platform = Linux, Language = Default, Definition = \"Ctrl+Q"
41 | #tag EndConstant
42 |
43 |
44 | End Class
45 | #tag EndClass
46 |
--------------------------------------------------------------------------------
/Harness Projects/Build Automation.xojo_code:
--------------------------------------------------------------------------------
1 | #tag BuildAutomation
2 | Begin BuildStepList Linux
3 | Begin BuildProjectStep Build
4 | End
5 | End
6 | Begin BuildStepList Mac OS X
7 | Begin BuildProjectStep Build
8 | End
9 | End
10 | Begin BuildStepList Windows
11 | Begin BuildProjectStep Build
12 | End
13 | End
14 | #tag EndBuildAutomation
15 |
--------------------------------------------------------------------------------
/Harness Projects/Examples/Eddies.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Module
2 | Protected Module Eddies
3 | #tag Constant, Name = kBaseURL, Type = Text, Dynamic = False, Default = \"http://demos.xojo.com/EEWS/index.cgi/api/", Scope = Private
4 | #tag EndConstant
5 |
6 |
7 | #tag ViewBehavior
8 | #tag ViewProperty
9 | Name="Index"
10 | Visible=true
11 | Group="ID"
12 | InitialValue="-2147483648"
13 | Type="Integer"
14 | #tag EndViewProperty
15 | #tag ViewProperty
16 | Name="Left"
17 | Visible=true
18 | Group="Position"
19 | InitialValue="0"
20 | Type="Integer"
21 | #tag EndViewProperty
22 | #tag ViewProperty
23 | Name="Name"
24 | Visible=true
25 | Group="ID"
26 | Type="String"
27 | #tag EndViewProperty
28 | #tag ViewProperty
29 | Name="Super"
30 | Visible=true
31 | Group="ID"
32 | Type="String"
33 | #tag EndViewProperty
34 | #tag ViewProperty
35 | Name="Top"
36 | Visible=true
37 | Group="Position"
38 | InitialValue="0"
39 | Type="Integer"
40 | #tag EndViewProperty
41 | #tag EndViewBehavior
42 | End Module
43 | #tag EndModule
44 |
--------------------------------------------------------------------------------
/Harness Projects/Examples/Eddies/Customer.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Protected Class Customer
3 | #tag Property, Flags = &h0
4 | City As Text
5 | #tag EndProperty
6 |
7 | #tag Property, Flags = &h0
8 | Email As Text
9 | #tag EndProperty
10 |
11 | #tag Property, Flags = &h0
12 | FirstName As Text
13 | #tag EndProperty
14 |
15 | #tag Property, Flags = &h0
16 | ID As Text
17 | #tag EndProperty
18 |
19 | #tag Property, Flags = &h0
20 | LastName As Text
21 | #tag EndProperty
22 |
23 | #tag Property, Flags = &h0
24 | Phone As Text
25 | #tag EndProperty
26 |
27 | #tag Property, Flags = &h0
28 | Photo As Picture
29 | #tag EndProperty
30 |
31 | #tag Property, Flags = &h0
32 | State As Text
33 | #tag EndProperty
34 |
35 | #tag Property, Flags = &h0
36 | Taxable As Boolean
37 | #tag EndProperty
38 |
39 | #tag Property, Flags = &h0
40 | Zip As Text
41 | #tag EndProperty
42 |
43 |
44 | #tag ViewBehavior
45 | #tag ViewProperty
46 | Name="City"
47 | Group="Behavior"
48 | Type="Text"
49 | #tag EndViewProperty
50 | #tag ViewProperty
51 | Name="Email"
52 | Group="Behavior"
53 | Type="Text"
54 | #tag EndViewProperty
55 | #tag ViewProperty
56 | Name="FirstName"
57 | Group="Behavior"
58 | Type="Text"
59 | #tag EndViewProperty
60 | #tag ViewProperty
61 | Name="ID"
62 | Group="Behavior"
63 | Type="Text"
64 | #tag EndViewProperty
65 | #tag ViewProperty
66 | Name="Index"
67 | Visible=true
68 | Group="ID"
69 | InitialValue="-2147483648"
70 | Type="Integer"
71 | #tag EndViewProperty
72 | #tag ViewProperty
73 | Name="LastName"
74 | Group="Behavior"
75 | Type="Text"
76 | #tag EndViewProperty
77 | #tag ViewProperty
78 | Name="Left"
79 | Visible=true
80 | Group="Position"
81 | InitialValue="0"
82 | Type="Integer"
83 | #tag EndViewProperty
84 | #tag ViewProperty
85 | Name="Name"
86 | Visible=true
87 | Group="ID"
88 | Type="String"
89 | #tag EndViewProperty
90 | #tag ViewProperty
91 | Name="Phone"
92 | Group="Behavior"
93 | Type="Text"
94 | #tag EndViewProperty
95 | #tag ViewProperty
96 | Name="Photo"
97 | Group="Behavior"
98 | Type="Picture"
99 | #tag EndViewProperty
100 | #tag ViewProperty
101 | Name="State"
102 | Group="Behavior"
103 | Type="Text"
104 | #tag EndViewProperty
105 | #tag ViewProperty
106 | Name="Super"
107 | Visible=true
108 | Group="ID"
109 | Type="String"
110 | #tag EndViewProperty
111 | #tag ViewProperty
112 | Name="Taxable"
113 | Group="Behavior"
114 | Type="Boolean"
115 | #tag EndViewProperty
116 | #tag ViewProperty
117 | Name="Top"
118 | Visible=true
119 | Group="Position"
120 | InitialValue="0"
121 | Type="Integer"
122 | #tag EndViewProperty
123 | #tag ViewProperty
124 | Name="Zip"
125 | Group="Behavior"
126 | Type="Text"
127 | #tag EndViewProperty
128 | #tag EndViewBehavior
129 | End Class
130 | #tag EndClass
131 |
--------------------------------------------------------------------------------
/Harness Projects/Examples/Eddies/GetCustomer.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Protected Class GetCustomer
3 | Inherits RESTMessage_MTC
4 | #tag Event
5 | Function GetRESTType() As RESTTypes
6 | return RESTTypes.POST
7 | End Function
8 | #tag EndEvent
9 |
10 | #tag Event
11 | Function GetURLPattern() As Text
12 | return kBaseURL + "GetCustomer"
13 | End Function
14 | #tag EndEvent
15 |
16 | #tag Event
17 | Function IncomingPayloadValueToProperty(value As Auto, prop As Xojo.Introspection.PropertyInfo, hostObject As Object) As Boolean
18 | if hostObject isa Customer then
19 |
20 | if prop.Name = "Photo" then
21 | dim textData as text = value
22 | dim binaryData as MemoryBlock = DecodeBase64( textData )
23 | dim p as Picture = Picture.FromData( binaryData )
24 | prop.Value( hostObject ) = p
25 | return true
26 |
27 | elseif prop.Name = "Taxable" then
28 | dim b as boolean = value = "1"
29 | prop.Value( hostObject ) = b
30 | return true
31 |
32 | end if
33 |
34 | end if
35 | End Function
36 | #tag EndEvent
37 |
38 |
39 | #tag Property, Flags = &h0
40 | ID As Text
41 | #tag EndProperty
42 |
43 | #tag Property, Flags = &h0
44 | ReturnGetCustomer As Customer
45 | #tag EndProperty
46 |
47 |
48 | #tag ViewBehavior
49 | #tag ViewProperty
50 | Name="DefaultRESTType"
51 | Visible=true
52 | Group="Behavior"
53 | InitialValue="RESTTypes.Unknown"
54 | Type="RESTTypes"
55 | EditorType="Enum"
56 | #tag EnumValues
57 | "0 - Unknown"
58 | "1 - Create"
59 | "2 - Read"
60 | "3 - UpdateReplace"
61 | "4 - UpdateModify"
62 | "5 - Authenticate"
63 | "6 - DELETE"
64 | "7 - GET"
65 | "8 - HEAD"
66 | "9 - OPTIONS"
67 | "10 - PATCH"
68 | "11 - POST"
69 | "12 - PUT"
70 | #tag EndEnumValues
71 | #tag EndViewProperty
72 | #tag ViewProperty
73 | Name="ID"
74 | Group="Behavior"
75 | Type="Text"
76 | #tag EndViewProperty
77 | #tag ViewProperty
78 | Name="Index"
79 | Visible=true
80 | Group="ID"
81 | InitialValue="-2147483648"
82 | Type="Integer"
83 | #tag EndViewProperty
84 | #tag ViewProperty
85 | Name="IsConnected"
86 | Group="Behavior"
87 | Type="Boolean"
88 | #tag EndViewProperty
89 | #tag ViewProperty
90 | Name="Left"
91 | Visible=true
92 | Group="Position"
93 | InitialValue="0"
94 | Type="Integer"
95 | #tag EndViewProperty
96 | #tag ViewProperty
97 | Name="MessageSerialNumber"
98 | Group="Behavior"
99 | Type="Int64"
100 | #tag EndViewProperty
101 | #tag ViewProperty
102 | Name="Name"
103 | Visible=true
104 | Group="ID"
105 | Type="String"
106 | #tag EndViewProperty
107 | #tag ViewProperty
108 | Name="RESTType"
109 | Group="Behavior"
110 | Type="RESTTypes"
111 | EditorType="Enum"
112 | #tag EnumValues
113 | "0 - Unknown"
114 | "1 - Create"
115 | "2 - Read"
116 | "3 - UpdateReplace"
117 | "4 - UpdateModify"
118 | "5 - Authenticate"
119 | "6 - DELETE"
120 | "7 - GET"
121 | "8 - HEAD"
122 | "9 - OPTIONS"
123 | "10 - PATCH"
124 | "11 - POST"
125 | "12 - PUT"
126 | #tag EndEnumValues
127 | #tag EndViewProperty
128 | #tag ViewProperty
129 | Name="RoundTripMs"
130 | Group="Behavior"
131 | Type="Double"
132 | #tag EndViewProperty
133 | #tag ViewProperty
134 | Name="RoundTripWithProcessingMs"
135 | Group="Behavior"
136 | Type="Double"
137 | #tag EndViewProperty
138 | #tag ViewProperty
139 | Name="Super"
140 | Visible=true
141 | Group="ID"
142 | Type="String"
143 | #tag EndViewProperty
144 | #tag ViewProperty
145 | Name="Top"
146 | Visible=true
147 | Group="Position"
148 | InitialValue="0"
149 | Type="Integer"
150 | #tag EndViewProperty
151 | #tag ViewProperty
152 | Name="ValidateCertificates"
153 | Visible=true
154 | Group="Behavior"
155 | Type="Boolean"
156 | #tag EndViewProperty
157 | #tag EndViewBehavior
158 | End Class
159 | #tag EndClass
160 |
--------------------------------------------------------------------------------
/Harness Projects/Examples/Eddies/GetCustomerList.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Protected Class GetCustomerList
3 | Inherits RESTMessage_MTC
4 | #tag Event
5 | Function GetRESTType() As RESTTypes
6 | return RESTTypes.GET
7 | End Function
8 | #tag EndEvent
9 |
10 | #tag Event
11 | Function GetURLPattern() As Text
12 | return kBaseURL + "GetAllCustomers"
13 | End Function
14 | #tag EndEvent
15 |
16 |
17 | #tag Property, Flags = &h0
18 | ReturnGetAllCustomers As Xojo.Core.Dictionary
19 | #tag EndProperty
20 |
21 |
22 | #tag ViewBehavior
23 | #tag ViewProperty
24 | Name="DefaultRESTType"
25 | Visible=true
26 | Group="Behavior"
27 | InitialValue="RESTTypes.Unknown"
28 | Type="RESTTypes"
29 | EditorType="Enum"
30 | #tag EnumValues
31 | "0 - Unknown"
32 | "1 - Create"
33 | "2 - Read"
34 | "3 - UpdateReplace"
35 | "4 - UpdateModify"
36 | "5 - Authenticate"
37 | "6 - DELETE"
38 | "7 - GET"
39 | "8 - HEAD"
40 | "9 - OPTIONS"
41 | "10 - PATCH"
42 | "11 - POST"
43 | "12 - PUT"
44 | #tag EndEnumValues
45 | #tag EndViewProperty
46 | #tag ViewProperty
47 | Name="Index"
48 | Visible=true
49 | Group="ID"
50 | InitialValue="-2147483648"
51 | Type="Integer"
52 | #tag EndViewProperty
53 | #tag ViewProperty
54 | Name="IsConnected"
55 | Group="Behavior"
56 | Type="Boolean"
57 | #tag EndViewProperty
58 | #tag ViewProperty
59 | Name="Left"
60 | Visible=true
61 | Group="Position"
62 | InitialValue="0"
63 | Type="Integer"
64 | #tag EndViewProperty
65 | #tag ViewProperty
66 | Name="MessageSerialNumber"
67 | Group="Behavior"
68 | Type="Int64"
69 | #tag EndViewProperty
70 | #tag ViewProperty
71 | Name="Name"
72 | Visible=true
73 | Group="ID"
74 | Type="String"
75 | #tag EndViewProperty
76 | #tag ViewProperty
77 | Name="RESTType"
78 | Group="Behavior"
79 | Type="RESTTypes"
80 | EditorType="Enum"
81 | #tag EnumValues
82 | "0 - Unknown"
83 | "1 - Create"
84 | "2 - Read"
85 | "3 - UpdateReplace"
86 | "4 - UpdateModify"
87 | "5 - Authenticate"
88 | "6 - DELETE"
89 | "7 - GET"
90 | "8 - HEAD"
91 | "9 - OPTIONS"
92 | "10 - PATCH"
93 | "11 - POST"
94 | "12 - PUT"
95 | #tag EndEnumValues
96 | #tag EndViewProperty
97 | #tag ViewProperty
98 | Name="RoundTripMs"
99 | Group="Behavior"
100 | Type="Double"
101 | #tag EndViewProperty
102 | #tag ViewProperty
103 | Name="RoundTripWithProcessingMs"
104 | Group="Behavior"
105 | Type="Double"
106 | #tag EndViewProperty
107 | #tag ViewProperty
108 | Name="Super"
109 | Visible=true
110 | Group="ID"
111 | Type="String"
112 | #tag EndViewProperty
113 | #tag ViewProperty
114 | Name="Top"
115 | Visible=true
116 | Group="Position"
117 | InitialValue="0"
118 | Type="Integer"
119 | #tag EndViewProperty
120 | #tag ViewProperty
121 | Name="ValidateCertificates"
122 | Visible=true
123 | Group="Behavior"
124 | Type="Boolean"
125 | #tag EndViewProperty
126 | #tag EndViewBehavior
127 | End Class
128 | #tag EndClass
129 |
--------------------------------------------------------------------------------
/Harness Projects/Examples/GetCatsMessage.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Protected Class GetCatsMessage
3 | Inherits RESTMessage_MTC
4 | #tag Event
5 | Function GetRESTType() As RESTTypes
6 | return RESTTypes.GET
7 | End Function
8 | #tag EndEvent
9 |
10 | #tag Event
11 | Function GetURLPattern() As Text
12 | return "http://thecatapi.com/api/images/get?format=:Format&results_per_page=:ResultsPerPage&size=:Size&type=:Type"
13 |
14 | End Function
15 | #tag EndEvent
16 |
17 |
18 | #tag Property, Flags = &h0
19 | Format As Text = "src"
20 | #tag EndProperty
21 |
22 | #tag Property, Flags = &h0
23 | ResultsPerPage As Integer = 1
24 | #tag EndProperty
25 |
26 | #tag Property, Flags = &h0
27 | ReturnPicture As Picture
28 | #tag EndProperty
29 |
30 | #tag Property, Flags = &h0
31 | Size As Text = "full"
32 | #tag EndProperty
33 |
34 | #tag Property, Flags = &h0
35 | Type As Text = "png"
36 | #tag EndProperty
37 |
38 |
39 | #tag ViewBehavior
40 | #tag ViewProperty
41 | Name="DefaultRESTType"
42 | Visible=true
43 | Group="Behavior"
44 | InitialValue="RESTTypes.Unknown"
45 | Type="RESTTypes"
46 | EditorType="Enum"
47 | #tag EnumValues
48 | "0 - Unknown"
49 | "1 - Create"
50 | "2 - Read"
51 | "3 - UpdateReplace"
52 | "4 - UpdateModify"
53 | "5 - Authenticate"
54 | "6 - DELETE"
55 | "7 - GET"
56 | "8 - HEAD"
57 | "9 - OPTIONS"
58 | "10 - PATCH"
59 | "11 - POST"
60 | "12 - PUT"
61 | #tag EndEnumValues
62 | #tag EndViewProperty
63 | #tag ViewProperty
64 | Name="Format"
65 | Visible=true
66 | Group="Behavior"
67 | InitialValue="src"
68 | Type="Text"
69 | #tag EndViewProperty
70 | #tag ViewProperty
71 | Name="Index"
72 | Visible=true
73 | Group="ID"
74 | InitialValue="-2147483648"
75 | Type="Integer"
76 | #tag EndViewProperty
77 | #tag ViewProperty
78 | Name="IsConnected"
79 | Group="Behavior"
80 | Type="Boolean"
81 | #tag EndViewProperty
82 | #tag ViewProperty
83 | Name="Left"
84 | Visible=true
85 | Group="Position"
86 | InitialValue="0"
87 | Type="Integer"
88 | #tag EndViewProperty
89 | #tag ViewProperty
90 | Name="MessageSerialNumber"
91 | Group="Behavior"
92 | Type="Int64"
93 | #tag EndViewProperty
94 | #tag ViewProperty
95 | Name="Name"
96 | Visible=true
97 | Group="ID"
98 | Type="String"
99 | #tag EndViewProperty
100 | #tag ViewProperty
101 | Name="RESTType"
102 | Group="Behavior"
103 | Type="RESTTypes"
104 | EditorType="Enum"
105 | #tag EnumValues
106 | "0 - Unknown"
107 | "1 - Create"
108 | "2 - Read"
109 | "3 - UpdateReplace"
110 | "4 - UpdateModify"
111 | "5 - Authenticate"
112 | "6 - DELETE"
113 | "7 - GET"
114 | "8 - HEAD"
115 | "9 - OPTIONS"
116 | "10 - PATCH"
117 | "11 - POST"
118 | "12 - PUT"
119 | #tag EndEnumValues
120 | #tag EndViewProperty
121 | #tag ViewProperty
122 | Name="ResultsPerPage"
123 | Visible=true
124 | Group="Behavior"
125 | InitialValue="1"
126 | Type="Integer"
127 | #tag EndViewProperty
128 | #tag ViewProperty
129 | Name="ReturnPicture"
130 | Group="Behavior"
131 | Type="Picture"
132 | #tag EndViewProperty
133 | #tag ViewProperty
134 | Name="RoundTripMs"
135 | Group="Behavior"
136 | Type="Double"
137 | #tag EndViewProperty
138 | #tag ViewProperty
139 | Name="RoundTripWithProcessingMs"
140 | Group="Behavior"
141 | Type="Double"
142 | #tag EndViewProperty
143 | #tag ViewProperty
144 | Name="Size"
145 | Visible=true
146 | Group="Behavior"
147 | InitialValue="full"
148 | Type="Text"
149 | #tag EndViewProperty
150 | #tag ViewProperty
151 | Name="Super"
152 | Visible=true
153 | Group="ID"
154 | Type="String"
155 | #tag EndViewProperty
156 | #tag ViewProperty
157 | Name="Top"
158 | Visible=true
159 | Group="Position"
160 | InitialValue="0"
161 | Type="Integer"
162 | #tag EndViewProperty
163 | #tag ViewProperty
164 | Name="Type"
165 | Visible=true
166 | Group="Behavior"
167 | InitialValue="jpg"
168 | Type="Text"
169 | #tag EndViewProperty
170 | #tag ViewProperty
171 | Name="ValidateCertificates"
172 | Visible=true
173 | Group="Behavior"
174 | Type="Boolean"
175 | #tag EndViewProperty
176 | #tag EndViewBehavior
177 | End Class
178 | #tag EndClass
179 |
--------------------------------------------------------------------------------
/Harness Projects/Examples/SQLFormatter.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Protected Class SQLFormatter
3 | Inherits RESTMessage_MTC
4 | #tag Event
5 | Function CancelSend(ByRef url As Text, ByRef httpAction As Text, ByRef payload As Xojo.Core.MemoryBlock, ByRef payloadMIMEType As Text) As Boolean
6 | #pragma unused url
7 | #pragma unused httpAction
8 |
9 | payloadMIMEType = "application/x-www-form-urlencoded"
10 |
11 | dim postText As text = "rqst_input_sql=" + EncodeURLComponent( InputSQL ).ToText + _
12 | "&rqst_db_vendor=" + DBVendor.ToText
13 |
14 | payload = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(postText)
15 |
16 | End Function
17 | #tag EndEvent
18 |
19 | #tag Event
20 | Function GetRESTType() As RESTTypes
21 | return RESTTypes.POST
22 | End Function
23 | #tag EndEvent
24 |
25 | #tag Event
26 | Function GetURLPattern() As Text
27 | return "http://www.gudusoft.com/format.php"
28 | End Function
29 | #tag EndEvent
30 |
31 | #tag Event
32 | Sub Setup()
33 | MessageOptions.SendWithPayloadIfAvailable = false // We'll handle it ourselves
34 | MessageOptions.ReturnPropertyPrefix = ""
35 | DBVendor = 1
36 |
37 | End Sub
38 | #tag EndEvent
39 |
40 |
41 | #tag Property, Flags = &h0
42 | DBVendor As Integer = 1
43 | #tag EndProperty
44 |
45 | #tag Property, Flags = &h0
46 | InputSQL As Text
47 | #tag EndProperty
48 |
49 | #tag Property, Flags = &h0
50 | Rspn_Formatted_SQL As Text
51 | #tag EndProperty
52 |
53 |
54 | #tag ViewBehavior
55 | #tag ViewProperty
56 | Name="DBVendor"
57 | Visible=true
58 | Group="Behavior"
59 | InitialValue="1"
60 | Type="Integer"
61 | #tag EndViewProperty
62 | #tag ViewProperty
63 | Name="DefaultRESTType"
64 | Visible=true
65 | Group="Behavior"
66 | InitialValue="RESTTypes.Unknown"
67 | Type="RESTTypes"
68 | EditorType="Enum"
69 | #tag EnumValues
70 | "0 - Unknown"
71 | "1 - Create"
72 | "2 - Read"
73 | "3 - UpdateReplace"
74 | "4 - UpdateModify"
75 | "5 - Authenticate"
76 | "6 - DELETE"
77 | "7 - GET"
78 | "8 - HEAD"
79 | "9 - OPTIONS"
80 | "10 - PATCH"
81 | "11 - POST"
82 | "12 - PUT"
83 | #tag EndEnumValues
84 | #tag EndViewProperty
85 | #tag ViewProperty
86 | Name="Index"
87 | Visible=true
88 | Group="ID"
89 | InitialValue="-2147483648"
90 | Type="Integer"
91 | #tag EndViewProperty
92 | #tag ViewProperty
93 | Name="InputSQL"
94 | Group="Behavior"
95 | Type="Text"
96 | #tag EndViewProperty
97 | #tag ViewProperty
98 | Name="IsConnected"
99 | Group="Behavior"
100 | Type="Boolean"
101 | #tag EndViewProperty
102 | #tag ViewProperty
103 | Name="Left"
104 | Visible=true
105 | Group="Position"
106 | InitialValue="0"
107 | Type="Integer"
108 | #tag EndViewProperty
109 | #tag ViewProperty
110 | Name="MessageSerialNumber"
111 | Group="Behavior"
112 | Type="Int64"
113 | #tag EndViewProperty
114 | #tag ViewProperty
115 | Name="Name"
116 | Visible=true
117 | Group="ID"
118 | Type="String"
119 | #tag EndViewProperty
120 | #tag ViewProperty
121 | Name="RESTType"
122 | Group="Behavior"
123 | Type="RESTTypes"
124 | EditorType="Enum"
125 | #tag EnumValues
126 | "0 - Unknown"
127 | "1 - Create"
128 | "2 - Read"
129 | "3 - UpdateReplace"
130 | "4 - UpdateModify"
131 | "5 - Authenticate"
132 | "6 - DELETE"
133 | "7 - GET"
134 | "8 - HEAD"
135 | "9 - OPTIONS"
136 | "10 - PATCH"
137 | "11 - POST"
138 | "12 - PUT"
139 | #tag EndEnumValues
140 | #tag EndViewProperty
141 | #tag ViewProperty
142 | Name="RoundTripMs"
143 | Group="Behavior"
144 | Type="Double"
145 | #tag EndViewProperty
146 | #tag ViewProperty
147 | Name="RoundTripWithProcessingMs"
148 | Group="Behavior"
149 | Type="Double"
150 | #tag EndViewProperty
151 | #tag ViewProperty
152 | Name="Rspn_Formatted_SQL"
153 | Group="Behavior"
154 | Type="Text"
155 | #tag EndViewProperty
156 | #tag ViewProperty
157 | Name="Super"
158 | Visible=true
159 | Group="ID"
160 | Type="String"
161 | #tag EndViewProperty
162 | #tag ViewProperty
163 | Name="Top"
164 | Visible=true
165 | Group="Position"
166 | InitialValue="0"
167 | Type="Integer"
168 | #tag EndViewProperty
169 | #tag ViewProperty
170 | Name="ValidateCertificates"
171 | Visible=true
172 | Group="Behavior"
173 | Type="Boolean"
174 | #tag EndViewProperty
175 | #tag EndViewBehavior
176 | End Class
177 | #tag EndClass
178 |
--------------------------------------------------------------------------------
/Harness Projects/MainMenuBar.xojo_menu:
--------------------------------------------------------------------------------
1 | #tag Menu
2 | Begin Menu MainMenuBar
3 | Begin MenuItem FileMenu
4 | SpecialMenu = 0
5 | Text = "&File"
6 | Index = -2147483648
7 | AutoEnable = True
8 | Visible = True
9 | Begin QuitMenuItem FileQuit
10 | SpecialMenu = 0
11 | Text = "#App.kFileQuit"
12 | Index = -2147483648
13 | ShortcutKey = "#App.kFileQuitShortcut"
14 | Shortcut = "#App.kFileQuitShortcut"
15 | AutoEnable = True
16 | Visible = True
17 | End
18 | End
19 | Begin MenuItem EditMenu
20 | SpecialMenu = 0
21 | Text = "&Edit"
22 | Index = -2147483648
23 | AutoEnable = True
24 | Visible = True
25 | Begin MenuItem EditUndo
26 | SpecialMenu = 0
27 | Text = "&Undo"
28 | Index = -2147483648
29 | ShortcutKey = "Z"
30 | Shortcut = "Cmd+Z"
31 | MenuModifier = True
32 | AutoEnable = True
33 | Visible = True
34 | End
35 | Begin MenuItem EditSeparator1
36 | SpecialMenu = 0
37 | Text = "-"
38 | Index = -2147483648
39 | AutoEnable = True
40 | Visible = True
41 | End
42 | Begin MenuItem EditCut
43 | SpecialMenu = 0
44 | Text = "Cu&t"
45 | Index = -2147483648
46 | ShortcutKey = "X"
47 | Shortcut = "Cmd+X"
48 | MenuModifier = True
49 | AutoEnable = True
50 | Visible = True
51 | End
52 | Begin MenuItem EditCopy
53 | SpecialMenu = 0
54 | Text = "&Copy"
55 | Index = -2147483648
56 | ShortcutKey = "C"
57 | Shortcut = "Cmd+C"
58 | MenuModifier = True
59 | AutoEnable = True
60 | Visible = True
61 | End
62 | Begin MenuItem EditPaste
63 | SpecialMenu = 0
64 | Text = "&Paste"
65 | Index = -2147483648
66 | ShortcutKey = "V"
67 | Shortcut = "Cmd+V"
68 | MenuModifier = True
69 | AutoEnable = True
70 | Visible = True
71 | End
72 | Begin MenuItem EditClear
73 | SpecialMenu = 0
74 | Text = "#App.kEditClear"
75 | Index = -2147483648
76 | AutoEnable = True
77 | Visible = True
78 | End
79 | Begin MenuItem EditSeparator2
80 | SpecialMenu = 0
81 | Text = "-"
82 | Index = -2147483648
83 | AutoEnable = True
84 | Visible = True
85 | End
86 | Begin MenuItem EditSelectAll
87 | SpecialMenu = 0
88 | Text = "Select &All"
89 | Index = -2147483648
90 | ShortcutKey = "A"
91 | Shortcut = "Cmd+A"
92 | MenuModifier = True
93 | AutoEnable = True
94 | Visible = True
95 | End
96 | End
97 | Begin MenuItem ExamplesMenu
98 | SpecialMenu = 0
99 | Text = "Examples"
100 | Index = -2147483648
101 | AutoEnable = True
102 | Visible = True
103 | Begin MenuItem ExamplesCats
104 | SpecialMenu = 0
105 | Text = "Cats"
106 | Index = -2147483648
107 | AutoEnable = True
108 | Visible = True
109 | End
110 | Begin MenuItem ExamplesEddies
111 | SpecialMenu = 0
112 | Text = "Eddie's Electronics"
113 | Index = -2147483648
114 | AutoEnable = True
115 | Visible = True
116 | End
117 | Begin MenuItem ExamplesSQLFormatter
118 | SpecialMenu = 0
119 | Text = "SQL Formatter"
120 | Index = -2147483648
121 | AutoEnable = True
122 | Visible = True
123 | End
124 | End
125 | End
126 | #tag EndMenu
127 |
--------------------------------------------------------------------------------
/Harness Projects/REST Harness.xojo_project:
--------------------------------------------------------------------------------
1 | Type=Desktop
2 | RBProjectVersion=2016.011
3 | MinIDEVersion=20070100
4 | Class=App;App.xojo_code;&h1EC067FF;&h0;false
5 | MenuBar=MainMenuBar;MainMenuBar.xojo_menu;&h5FF8CFFF;&h0;false
6 | BuildSteps=Build Automation;Build Automation.xojo_code;&h3B4A37FF;&h0;false
7 | Module=M_REST;../REST Resources/M_REST.xojo_code;&h608AF7FF;&hF907FFF;false
8 | Class=Options;../REST Resources/M_REST/Options.xojo_code;&h37BAA7FF;&h608AF7FF;false
9 | Class=RESTException;../REST Resources/M_REST/RESTException.xojo_code;&h394E8FFF;&h608AF7FF;false
10 | Class=RESTMessage_MTC;../REST Resources/M_REST/RESTMessage_MTC.xojo_code;&h109DCFFF;&h608AF7FF;false
11 | Class=RESTMessageSurrogate_MTC;../REST Resources/M_REST/RESTMessageSurrogate_MTC.xojo_code;&h677777FF;&h608AF7FF;false
12 | Interface=TextProvider;../REST Resources/M_REST/TextProvider.xojo_code;&h1F1CC7FF;&h608AF7FF;false
13 | Class=ClassMeta;../REST Resources/M_REST/ClassMeta.xojo_code;&h5961FFF;&h608AF7FF;false
14 | Folder=Examples;Examples;&h51D0A7FF;&h0;false
15 | Module=Eddies;Examples/Eddies.xojo_code;&h5784FFFF;&h51D0A7FF;false
16 | Class=GetCatsMessage;Examples/GetCatsMessage.xojo_code;&h5EC0D7FF;&h51D0A7FF;false
17 | Interface=PrivateMessage;../REST Resources/M_REST/PrivateMessage.xojo_code;&h6F4757FF;&h608AF7FF;false
18 | Interface=PrivateOptions;../REST Resources/M_REST/PrivateOptions.xojo_code;&h7E44C7FF;&h608AF7FF;false
19 | Class=SQLFormatter;Examples/SQLFormatter.xojo_code;&h64EFFFF;&h51D0A7FF;false
20 | Folder=Windows Folder;Windows Folder;&h6FA08FFF;&h0;false
21 | Window=WndMain;Windows Folder/WndMain.xojo_window;&h8156FFF;&h6FA08FFF;false
22 | Folder=REST Resources;../REST Resources;&hF907FFF;&h0;false
23 | Window=WndCats;Windows Folder/WndCats.xojo_window;&h26C787FF;&h6FA08FFF;false
24 | Window=WndEddies;Windows Folder/WndEddies.xojo_window;&h104087FF;&h6FA08FFF;false
25 | Window=WndSQLFormatter;Windows Folder/WndSQLFormatter.xojo_window;&h79F357FF;&h6FA08FFF;false
26 | Class=GetCustomerList;Examples/Eddies/GetCustomerList.xojo_code;&h54E4DFFF;&h5784FFFF;false
27 | Class=GetCustomer;Examples/Eddies/GetCustomer.xojo_code;&h6C67FFFF;&h5784FFFF;false
28 | Class=Customer;Examples/Eddies/Customer.xojo_code;&h7E394FFF;&h5784FFFF;false
29 | Interface=PrivateSurrogate;../REST Resources/M_REST/PrivateSurrogate.xojo_code;&h25EB87FF;&h608AF7FF;false
30 | DefaultWindow=WndMain
31 | AppMenuBar=MainMenuBar
32 | MajorVersion=1
33 | MinorVersion=0
34 | SubVersion=0
35 | NonRelease=0
36 | Release=0
37 | InfoVersion=
38 | LongVersion=
39 | ShortVersion=
40 | WinCompanyName=MacTechnologies Consulting
41 | WinInternalName=
42 | WinProductName=
43 | WinFileDescription=
44 | AutoIncrementVersionInformation=False
45 | BuildFlags=&h4900
46 | BuildLanguage=&h0
47 | DebugLanguage=&h0
48 | Region=
49 | WindowsName=REST Harness.exe
50 | MacCarbonMachName=REST Harness
51 | LinuxX86Name=REST Harness
52 | MacCreator=
53 | MDI=0
54 | MDICaption=
55 | DefaultEncoding=&h0
56 | AppIcon=REST Harness.xojo_resources;&h0
57 | OSXBundleID=com.mactechnologiesconsulting.restharness
58 | DebuggerCommandLine=
59 | UseGDIPlus=False
60 | UseBuildsFolder=True
61 | IsWebProject=False
62 |
--------------------------------------------------------------------------------
/Harness Projects/REST Harness.xojo_resources:
--------------------------------------------------------------------------------
1 | ICNS
--------------------------------------------------------------------------------
/Harness Projects/Windows Folder/WndCats.xojo_window:
--------------------------------------------------------------------------------
1 | #tag Window
2 | Begin Window WndCats
3 | BackColor = &cFFFFFF00
4 | Backdrop = 0
5 | CloseButton = True
6 | Compatibility = ""
7 | Composite = False
8 | Frame = 0
9 | FullScreen = False
10 | FullScreenButton= False
11 | HasBackColor = False
12 | Height = 400
13 | ImplicitInstance= True
14 | LiveResize = True
15 | MacProcID = 0
16 | MaxHeight = 32000
17 | MaximizeButton = True
18 | MaxWidth = 32000
19 | MenuBar = 1610141695
20 | MenuBarVisible = True
21 | MinHeight = 400
22 | MinimizeButton = True
23 | MinWidth = 600
24 | Placement = 0
25 | Resizeable = True
26 | Title = "Cats"
27 | Visible = True
28 | Width = 600
29 | Begin GetCatsMessage msgGetCats
30 | DefaultRESTType = "7"
31 | Enabled = True
32 | Format = "src"
33 | Index = -2147483648
34 | IsConnected = False
35 | LockedInPosition= False
36 | MessageSerialNumber= ""
37 | RESTType = "7"
38 | ResultsPerPage = 1
39 | ReturnPicture = 0
40 | RoundTripMs = 0.0
41 | RoundTripWithProcessingMs= 0.0
42 | Scope = 2
43 | Size = "full"
44 | TabPanelIndex = 0
45 | Type = "png"
46 | ValidateCertificates= False
47 | End
48 | Begin PushButton btnGetCat
49 | AutoDeactivate = True
50 | Bold = False
51 | ButtonStyle = "0"
52 | Cancel = False
53 | Caption = "Get Cat"
54 | Default = False
55 | Enabled = True
56 | Height = 20
57 | HelpTag = ""
58 | Index = -2147483648
59 | InitialParent = ""
60 | Italic = False
61 | Left = 20
62 | LockBottom = False
63 | LockedInPosition= False
64 | LockLeft = True
65 | LockRight = False
66 | LockTop = True
67 | Scope = 2
68 | TabIndex = 0
69 | TabPanelIndex = 0
70 | TabStop = True
71 | TextFont = "System"
72 | TextSize = 0.0
73 | TextUnit = 0
74 | Top = 20
75 | Underline = False
76 | Visible = True
77 | Width = 80
78 | End
79 | Begin Canvas cvsPic
80 | AcceptFocus = False
81 | AcceptTabs = False
82 | AutoDeactivate = True
83 | Backdrop = 0
84 | DoubleBuffer = False
85 | Enabled = True
86 | EraseBackground = True
87 | Height = 328
88 | HelpTag = ""
89 | Index = -2147483648
90 | InitialParent = ""
91 | Left = 20
92 | LockBottom = True
93 | LockedInPosition= False
94 | LockLeft = True
95 | LockRight = True
96 | LockTop = True
97 | Scope = 2
98 | TabIndex = 1
99 | TabPanelIndex = 0
100 | TabStop = True
101 | Top = 52
102 | Transparent = True
103 | UseFocusRing = True
104 | Visible = True
105 | Width = 560
106 | End
107 | End
108 | #tag EndWindow
109 |
110 | #tag WindowCode
111 | #tag Property, Flags = &h21
112 | Private CatPic As Picture
113 | #tag EndProperty
114 |
115 |
116 | #tag EndWindowCode
117 |
118 | #tag Events msgGetCats
119 | #tag Event
120 | Sub ResponseReceived(url As Text, httpStatus As Integer, payload As Auto)
121 | #pragma unused url
122 | #pragma unused httpStatus
123 | #pragma unused payload
124 |
125 | cvsPic.Invalidate
126 | return
127 |
128 | End Sub
129 | #tag EndEvent
130 | #tag EndEvents
131 | #tag Events btnGetCat
132 | #tag Event
133 | Sub Action()
134 | msgGetCats.Send
135 | End Sub
136 | #tag EndEvent
137 | #tag EndEvents
138 | #tag Events cvsPic
139 | #tag Event
140 | Sub Paint(g As Graphics, areas() As REALbasic.Rect)
141 | #pragma unused areas
142 |
143 | dim catPic as Picture = msgGetCats.ReturnPicture
144 |
145 | if catPic is nil then
146 |
147 | g.ClearRect 0, 0, g.Width, g.Height
148 |
149 | else
150 |
151 | g.DrawPicture catPic, 0, 0, g.Width, g.Height, 0, 0, CatPic.Width, CatPic.Height
152 |
153 | end if
154 | End Sub
155 | #tag EndEvent
156 | #tag EndEvents
157 | #tag ViewBehavior
158 | #tag ViewProperty
159 | Name="BackColor"
160 | Visible=true
161 | Group="Background"
162 | InitialValue="&hFFFFFF"
163 | Type="Color"
164 | #tag EndViewProperty
165 | #tag ViewProperty
166 | Name="Backdrop"
167 | Visible=true
168 | Group="Background"
169 | Type="Picture"
170 | EditorType="Picture"
171 | #tag EndViewProperty
172 | #tag ViewProperty
173 | Name="CloseButton"
174 | Visible=true
175 | Group="Frame"
176 | InitialValue="True"
177 | Type="Boolean"
178 | EditorType="Boolean"
179 | #tag EndViewProperty
180 | #tag ViewProperty
181 | Name="Composite"
182 | Group="OS X (Carbon)"
183 | InitialValue="False"
184 | Type="Boolean"
185 | #tag EndViewProperty
186 | #tag ViewProperty
187 | Name="Frame"
188 | Visible=true
189 | Group="Frame"
190 | InitialValue="0"
191 | Type="Integer"
192 | EditorType="Enum"
193 | #tag EnumValues
194 | "0 - Document"
195 | "1 - Movable Modal"
196 | "2 - Modal Dialog"
197 | "3 - Floating Window"
198 | "4 - Plain Box"
199 | "5 - Shadowed Box"
200 | "6 - Rounded Window"
201 | "7 - Global Floating Window"
202 | "8 - Sheet Window"
203 | "9 - Metal Window"
204 | "11 - Modeless Dialog"
205 | #tag EndEnumValues
206 | #tag EndViewProperty
207 | #tag ViewProperty
208 | Name="FullScreen"
209 | Group="Behavior"
210 | InitialValue="False"
211 | Type="Boolean"
212 | EditorType="Boolean"
213 | #tag EndViewProperty
214 | #tag ViewProperty
215 | Name="FullScreenButton"
216 | Visible=true
217 | Group="Frame"
218 | InitialValue="False"
219 | Type="Boolean"
220 | EditorType="Boolean"
221 | #tag EndViewProperty
222 | #tag ViewProperty
223 | Name="HasBackColor"
224 | Visible=true
225 | Group="Background"
226 | InitialValue="False"
227 | Type="Boolean"
228 | #tag EndViewProperty
229 | #tag ViewProperty
230 | Name="Height"
231 | Visible=true
232 | Group="Size"
233 | InitialValue="400"
234 | Type="Integer"
235 | #tag EndViewProperty
236 | #tag ViewProperty
237 | Name="ImplicitInstance"
238 | Visible=true
239 | Group="Behavior"
240 | InitialValue="True"
241 | Type="Boolean"
242 | EditorType="Boolean"
243 | #tag EndViewProperty
244 | #tag ViewProperty
245 | Name="Interfaces"
246 | Visible=true
247 | Group="ID"
248 | Type="String"
249 | EditorType="String"
250 | #tag EndViewProperty
251 | #tag ViewProperty
252 | Name="LiveResize"
253 | Visible=true
254 | Group="Behavior"
255 | InitialValue="True"
256 | Type="Boolean"
257 | EditorType="Boolean"
258 | #tag EndViewProperty
259 | #tag ViewProperty
260 | Name="MacProcID"
261 | Group="OS X (Carbon)"
262 | InitialValue="0"
263 | Type="Integer"
264 | #tag EndViewProperty
265 | #tag ViewProperty
266 | Name="MaxHeight"
267 | Visible=true
268 | Group="Size"
269 | InitialValue="32000"
270 | Type="Integer"
271 | #tag EndViewProperty
272 | #tag ViewProperty
273 | Name="MaximizeButton"
274 | Visible=true
275 | Group="Frame"
276 | InitialValue="True"
277 | Type="Boolean"
278 | EditorType="Boolean"
279 | #tag EndViewProperty
280 | #tag ViewProperty
281 | Name="MaxWidth"
282 | Visible=true
283 | Group="Size"
284 | InitialValue="32000"
285 | Type="Integer"
286 | #tag EndViewProperty
287 | #tag ViewProperty
288 | Name="MenuBar"
289 | Visible=true
290 | Group="Menus"
291 | Type="MenuBar"
292 | EditorType="MenuBar"
293 | #tag EndViewProperty
294 | #tag ViewProperty
295 | Name="MenuBarVisible"
296 | Group="Behavior"
297 | InitialValue="True"
298 | Type="Boolean"
299 | EditorType="Boolean"
300 | #tag EndViewProperty
301 | #tag ViewProperty
302 | Name="MinHeight"
303 | Visible=true
304 | Group="Size"
305 | InitialValue="64"
306 | Type="Integer"
307 | #tag EndViewProperty
308 | #tag ViewProperty
309 | Name="MinimizeButton"
310 | Visible=true
311 | Group="Frame"
312 | InitialValue="True"
313 | Type="Boolean"
314 | EditorType="Boolean"
315 | #tag EndViewProperty
316 | #tag ViewProperty
317 | Name="MinWidth"
318 | Visible=true
319 | Group="Size"
320 | InitialValue="64"
321 | Type="Integer"
322 | #tag EndViewProperty
323 | #tag ViewProperty
324 | Name="Name"
325 | Visible=true
326 | Group="ID"
327 | Type="String"
328 | EditorType="String"
329 | #tag EndViewProperty
330 | #tag ViewProperty
331 | Name="Placement"
332 | Visible=true
333 | Group="Behavior"
334 | InitialValue="0"
335 | Type="Integer"
336 | EditorType="Enum"
337 | #tag EnumValues
338 | "0 - Default"
339 | "1 - Parent Window"
340 | "2 - Main Screen"
341 | "3 - Parent Window Screen"
342 | "4 - Stagger"
343 | #tag EndEnumValues
344 | #tag EndViewProperty
345 | #tag ViewProperty
346 | Name="Resizeable"
347 | Visible=true
348 | Group="Frame"
349 | InitialValue="True"
350 | Type="Boolean"
351 | EditorType="Boolean"
352 | #tag EndViewProperty
353 | #tag ViewProperty
354 | Name="Super"
355 | Visible=true
356 | Group="ID"
357 | Type="String"
358 | EditorType="String"
359 | #tag EndViewProperty
360 | #tag ViewProperty
361 | Name="Title"
362 | Visible=true
363 | Group="Frame"
364 | InitialValue="Untitled"
365 | Type="String"
366 | #tag EndViewProperty
367 | #tag ViewProperty
368 | Name="Visible"
369 | Visible=true
370 | Group="Behavior"
371 | InitialValue="True"
372 | Type="Boolean"
373 | EditorType="Boolean"
374 | #tag EndViewProperty
375 | #tag ViewProperty
376 | Name="Width"
377 | Visible=true
378 | Group="Size"
379 | InitialValue="600"
380 | Type="Integer"
381 | #tag EndViewProperty
382 | #tag EndViewBehavior
383 |
--------------------------------------------------------------------------------
/Harness Projects/Windows Folder/WndEddies.xojo_window:
--------------------------------------------------------------------------------
1 | #tag Window
2 | Begin Window WndEddies
3 | BackColor = &cFFFFFF00
4 | Backdrop = 0
5 | CloseButton = True
6 | Compatibility = ""
7 | Composite = False
8 | Frame = 0
9 | FullScreen = False
10 | FullScreenButton= False
11 | HasBackColor = False
12 | Height = 508
13 | ImplicitInstance= True
14 | LiveResize = True
15 | MacProcID = 0
16 | MaxHeight = 508
17 | MaximizeButton = True
18 | MaxWidth = 758
19 | MenuBar = 0
20 | MenuBarVisible = True
21 | MinHeight = 508
22 | MinimizeButton = True
23 | MinWidth = 758
24 | Placement = 0
25 | Resizeable = True
26 | Title = "Eddies Electronics"
27 | Visible = True
28 | Width = 758
29 | Begin Eddies.GetCustomerList msgGetCustomerList
30 | DefaultRESTType = "RESTTypes.Unknown"
31 | Enabled = True
32 | Index = -2147483648
33 | IsConnected = False
34 | LockedInPosition= False
35 | MessageSerialNumber= ""
36 | RESTType = ""
37 | RoundTripMs = 0.0
38 | RoundTripWithProcessingMs= 0.0
39 | Scope = 2
40 | TabPanelIndex = 0
41 | ValidateCertificates= False
42 | End
43 | Begin Eddies.GetCustomer msgGetCustomer
44 | DefaultRESTType = "RESTTypes.Unknown"
45 | Enabled = True
46 | ID = 0
47 | Index = -2147483648
48 | IsConnected = False
49 | LockedInPosition= False
50 | MessageSerialNumber= ""
51 | RESTType = ""
52 | RoundTripMs = 0.0
53 | RoundTripWithProcessingMs= 0.0
54 | Scope = 2
55 | TabPanelIndex = 0
56 | ValidateCertificates= False
57 | End
58 | Begin Listbox lbCustomers
59 | AutoDeactivate = True
60 | AutoHideScrollbars= True
61 | Bold = False
62 | Border = True
63 | ColumnCount = 2
64 | ColumnsResizable= False
65 | ColumnWidths = "20%"
66 | DataField = ""
67 | DataSource = ""
68 | DefaultRowHeight= -1
69 | Enabled = True
70 | EnableDrag = False
71 | EnableDragReorder= False
72 | GridLinesHorizontal= 0
73 | GridLinesVertical= 0
74 | HasHeading = True
75 | HeadingIndex = -1
76 | Height = 468
77 | HelpTag = ""
78 | Hierarchical = False
79 | Index = -2147483648
80 | InitialParent = ""
81 | InitialValue = "ID Name"
82 | Italic = False
83 | Left = 20
84 | LockBottom = False
85 | LockedInPosition= False
86 | LockLeft = True
87 | LockRight = False
88 | LockTop = True
89 | RequiresSelection= False
90 | Scope = 2
91 | ScrollbarHorizontal= False
92 | ScrollBarVertical= True
93 | SelectionType = 0
94 | TabIndex = 0
95 | TabPanelIndex = 0
96 | TabStop = True
97 | TextFont = "System"
98 | TextSize = 0.0
99 | TextUnit = 0
100 | Top = 20
101 | Underline = False
102 | UseFocusRing = True
103 | Visible = True
104 | Width = 298
105 | _ScrollOffset = 0
106 | _ScrollWidth = -1
107 | End
108 | Begin TextField fldFirstName
109 | AcceptTabs = False
110 | Alignment = 0
111 | AutoDeactivate = True
112 | AutomaticallyCheckSpelling= False
113 | BackColor = &cFFFFFF00
114 | Bold = False
115 | Border = True
116 | CueText = "First Name"
117 | DataField = ""
118 | DataSource = ""
119 | Enabled = True
120 | Format = ""
121 | Height = 22
122 | HelpTag = ""
123 | Index = -2147483648
124 | Italic = False
125 | Left = 397
126 | LimitText = 0
127 | LockBottom = False
128 | LockedInPosition= False
129 | LockLeft = True
130 | LockRight = False
131 | LockTop = True
132 | Mask = ""
133 | Password = False
134 | ReadOnly = False
135 | Scope = 2
136 | TabIndex = 1
137 | TabPanelIndex = 0
138 | TabStop = True
139 | Text = ""
140 | TextColor = &c00000000
141 | TextFont = "System"
142 | TextSize = 0.0
143 | TextUnit = 0
144 | Top = 278
145 | Underline = False
146 | UseFocusRing = True
147 | Visible = True
148 | Width = 162
149 | End
150 | Begin TextField fldLastName
151 | AcceptTabs = False
152 | Alignment = 0
153 | AutoDeactivate = True
154 | AutomaticallyCheckSpelling= False
155 | BackColor = &cFFFFFF00
156 | Bold = False
157 | Border = True
158 | CueText = "Last Name"
159 | DataField = ""
160 | DataSource = ""
161 | Enabled = True
162 | Format = ""
163 | Height = 22
164 | HelpTag = ""
165 | Index = -2147483648
166 | Italic = False
167 | Left = 571
168 | LimitText = 0
169 | LockBottom = False
170 | LockedInPosition= False
171 | LockLeft = True
172 | LockRight = False
173 | LockTop = True
174 | Mask = ""
175 | Password = False
176 | ReadOnly = False
177 | Scope = 2
178 | TabIndex = 2
179 | TabPanelIndex = 0
180 | TabStop = True
181 | Text = ""
182 | TextColor = &c00000000
183 | TextFont = "System"
184 | TextSize = 0.0
185 | TextUnit = 0
186 | Top = 278
187 | Underline = False
188 | UseFocusRing = True
189 | Visible = True
190 | Width = 162
191 | End
192 | Begin TextField fldCity
193 | AcceptTabs = False
194 | Alignment = 0
195 | AutoDeactivate = True
196 | AutomaticallyCheckSpelling= False
197 | BackColor = &cFFFFFF00
198 | Bold = False
199 | Border = True
200 | CueText = "City"
201 | DataField = ""
202 | DataSource = ""
203 | Enabled = True
204 | Format = ""
205 | Height = 22
206 | HelpTag = ""
207 | Index = -2147483648
208 | Italic = False
209 | Left = 397
210 | LimitText = 0
211 | LockBottom = False
212 | LockedInPosition= False
213 | LockLeft = True
214 | LockRight = False
215 | LockTop = True
216 | Mask = ""
217 | Password = False
218 | ReadOnly = False
219 | Scope = 2
220 | TabIndex = 3
221 | TabPanelIndex = 0
222 | TabStop = True
223 | Text = ""
224 | TextColor = &c00000000
225 | TextFont = "System"
226 | TextSize = 0.0
227 | TextUnit = 0
228 | Top = 312
229 | Underline = False
230 | UseFocusRing = True
231 | Visible = True
232 | Width = 162
233 | End
234 | Begin TextField fldState
235 | AcceptTabs = False
236 | Alignment = 0
237 | AutoDeactivate = True
238 | AutomaticallyCheckSpelling= False
239 | BackColor = &cFFFFFF00
240 | Bold = False
241 | Border = True
242 | CueText = "State"
243 | DataField = ""
244 | DataSource = ""
245 | Enabled = True
246 | Format = ""
247 | Height = 22
248 | HelpTag = ""
249 | Index = -2147483648
250 | Italic = False
251 | Left = 571
252 | LimitText = 0
253 | LockBottom = False
254 | LockedInPosition= False
255 | LockLeft = True
256 | LockRight = False
257 | LockTop = True
258 | Mask = ""
259 | Password = False
260 | ReadOnly = False
261 | Scope = 2
262 | TabIndex = 4
263 | TabPanelIndex = 0
264 | TabStop = True
265 | Text = ""
266 | TextColor = &c00000000
267 | TextFont = "System"
268 | TextSize = 0.0
269 | TextUnit = 0
270 | Top = 312
271 | Underline = False
272 | UseFocusRing = True
273 | Visible = True
274 | Width = 47
275 | End
276 | Begin TextField fldZip
277 | AcceptTabs = False
278 | Alignment = 0
279 | AutoDeactivate = True
280 | AutomaticallyCheckSpelling= False
281 | BackColor = &cFFFFFF00
282 | Bold = False
283 | Border = True
284 | CueText = "Zip"
285 | DataField = ""
286 | DataSource = ""
287 | Enabled = True
288 | Format = ""
289 | Height = 22
290 | HelpTag = ""
291 | Index = -2147483648
292 | Italic = False
293 | Left = 630
294 | LimitText = 0
295 | LockBottom = False
296 | LockedInPosition= False
297 | LockLeft = True
298 | LockRight = False
299 | LockTop = True
300 | Mask = ""
301 | Password = False
302 | ReadOnly = False
303 | Scope = 2
304 | TabIndex = 5
305 | TabPanelIndex = 0
306 | TabStop = True
307 | Text = ""
308 | TextColor = &c00000000
309 | TextFont = "System"
310 | TextSize = 0.0
311 | TextUnit = 0
312 | Top = 312
313 | Underline = False
314 | UseFocusRing = True
315 | Visible = True
316 | Width = 103
317 | End
318 | Begin TextField fldPhone
319 | AcceptTabs = False
320 | Alignment = 0
321 | AutoDeactivate = True
322 | AutomaticallyCheckSpelling= False
323 | BackColor = &cFFFFFF00
324 | Bold = False
325 | Border = True
326 | CueText = "Phone"
327 | DataField = ""
328 | DataSource = ""
329 | Enabled = True
330 | Format = ""
331 | Height = 22
332 | HelpTag = ""
333 | Index = -2147483648
334 | Italic = False
335 | Left = 397
336 | LimitText = 0
337 | LockBottom = False
338 | LockedInPosition= False
339 | LockLeft = True
340 | LockRight = False
341 | LockTop = True
342 | Mask = ""
343 | Password = False
344 | ReadOnly = False
345 | Scope = 2
346 | TabIndex = 6
347 | TabPanelIndex = 0
348 | TabStop = True
349 | Text = ""
350 | TextColor = &c00000000
351 | TextFont = "System"
352 | TextSize = 0.0
353 | TextUnit = 0
354 | Top = 346
355 | Underline = False
356 | UseFocusRing = True
357 | Visible = True
358 | Width = 162
359 | End
360 | Begin TextField fldEmail
361 | AcceptTabs = False
362 | Alignment = 0
363 | AutoDeactivate = True
364 | AutomaticallyCheckSpelling= False
365 | BackColor = &cFFFFFF00
366 | Bold = False
367 | Border = True
368 | CueText = "E-mail"
369 | DataField = ""
370 | DataSource = ""
371 | Enabled = True
372 | Format = ""
373 | Height = 22
374 | HelpTag = ""
375 | Index = -2147483648
376 | Italic = False
377 | Left = 571
378 | LimitText = 0
379 | LockBottom = False
380 | LockedInPosition= False
381 | LockLeft = True
382 | LockRight = False
383 | LockTop = True
384 | Mask = ""
385 | Password = False
386 | ReadOnly = False
387 | Scope = 2
388 | TabIndex = 7
389 | TabPanelIndex = 0
390 | TabStop = True
391 | Text = ""
392 | TextColor = &c00000000
393 | TextFont = "System"
394 | TextSize = 0.0
395 | TextUnit = 0
396 | Top = 346
397 | Underline = False
398 | UseFocusRing = True
399 | Visible = True
400 | Width = 162
401 | End
402 | Begin Canvas cvsPhoto
403 | AcceptFocus = False
404 | AcceptTabs = False
405 | AutoDeactivate = True
406 | Backdrop = 0
407 | DoubleBuffer = False
408 | Enabled = True
409 | EraseBackground = True
410 | Height = 192
411 | HelpTag = ""
412 | Index = -2147483648
413 | InitialParent = ""
414 | Left = 397
415 | LockBottom = False
416 | LockedInPosition= False
417 | LockLeft = True
418 | LockRight = False
419 | LockTop = True
420 | Scope = 2
421 | TabIndex = 8
422 | TabPanelIndex = 0
423 | TabStop = True
424 | Top = 20
425 | Transparent = True
426 | UseFocusRing = True
427 | Visible = True
428 | Width = 192
429 | End
430 | Begin CheckBox cbTaxable
431 | AutoDeactivate = True
432 | Bold = False
433 | Caption = "Taxable"
434 | DataField = ""
435 | DataSource = ""
436 | Enabled = True
437 | Height = 20
438 | HelpTag = ""
439 | Index = -2147483648
440 | InitialParent = ""
441 | Italic = False
442 | Left = 397
443 | LockBottom = False
444 | LockedInPosition= False
445 | LockLeft = True
446 | LockRight = False
447 | LockTop = True
448 | Scope = 2
449 | State = 0
450 | TabIndex = 9
451 | TabPanelIndex = 0
452 | TabStop = True
453 | TextFont = "System"
454 | TextSize = 0.0
455 | TextUnit = 0
456 | Top = 380
457 | Underline = False
458 | Value = False
459 | Visible = True
460 | Width = 100
461 | End
462 | Begin Timer tmrUpdateControls
463 | Enabled = True
464 | Index = -2147483648
465 | LockedInPosition= False
466 | Mode = 2
467 | Period = 250
468 | Scope = 2
469 | TabPanelIndex = 0
470 | End
471 | Begin Label lblRoundtrip
472 | AutoDeactivate = True
473 | Bold = False
474 | DataField = ""
475 | DataSource = ""
476 | Enabled = True
477 | Height = 20
478 | HelpTag = ""
479 | Index = -2147483648
480 | InitialParent = ""
481 | Italic = True
482 | Left = 561
483 | LockBottom = False
484 | LockedInPosition= False
485 | LockLeft = True
486 | LockRight = False
487 | LockTop = True
488 | Multiline = False
489 | Scope = 2
490 | Selectable = False
491 | TabIndex = 10
492 | TabPanelIndex = 0
493 | TabStop = True
494 | Text = "RoundTrip"
495 | TextAlign = 2
496 | TextColor = &c00000000
497 | TextFont = "SmallSystem"
498 | TextSize = 0.0
499 | TextUnit = 0
500 | Top = 468
501 | Transparent = True
502 | Underline = False
503 | Visible = True
504 | Width = 177
505 | End
506 | Begin CheckBox cbStore
507 | AutoDeactivate = True
508 | Bold = False
509 | Caption = "Store Customers"
510 | DataField = ""
511 | DataSource = ""
512 | Enabled = True
513 | Height = 20
514 | HelpTag = ""
515 | Index = -2147483648
516 | InitialParent = ""
517 | Italic = False
518 | Left = 601
519 | LockBottom = False
520 | LockedInPosition= False
521 | LockLeft = True
522 | LockRight = False
523 | LockTop = True
524 | Scope = 2
525 | State = 0
526 | TabIndex = 11
527 | TabPanelIndex = 0
528 | TabStop = True
529 | TextFont = "System"
530 | TextSize = 0.0
531 | TextUnit = 0
532 | Top = 20
533 | Underline = False
534 | Value = False
535 | Visible = True
536 | Width = 129
537 | End
538 | Begin M_REST.RESTMessageSurrogate_MTC smsgGetCustomerSurrogate
539 | Enabled = True
540 | Index = -2147483648
541 | IsBusy = False
542 | LockedInPosition= False
543 | Scope = 2
544 | TabPanelIndex = 0
545 | End
546 | Begin ProgressWheel pwBusy
547 | AutoDeactivate = True
548 | Enabled = True
549 | Height = 16
550 | HelpTag = ""
551 | Index = -2147483648
552 | InitialParent = ""
553 | Left = 344
554 | LockBottom = False
555 | LockedInPosition= False
556 | LockLeft = True
557 | LockRight = False
558 | LockTop = True
559 | Scope = 2
560 | TabIndex = 12
561 | TabPanelIndex = 0
562 | TabStop = True
563 | Top = 468
564 | Visible = True
565 | Width = 16
566 | End
567 | End
568 | #tag EndWindow
569 |
570 | #tag WindowCode
571 | #tag Event
572 | Sub Open()
573 | msgGetCustomerList.Send
574 | pwBusy.Visible = true
575 | End Sub
576 | #tag EndEvent
577 |
578 |
579 | #tag Method, Flags = &h21
580 | Private Sub ClearFields()
581 | fldFirstName.Text = ""
582 | fldLastName.Text = ""
583 | fldCity.Text = ""
584 | fldState.Text = ""
585 | fldZip.Text = ""
586 | fldEmail.Text = ""
587 | fldPhone.Text = ""
588 |
589 | cvsPhoto.Invalidate
590 |
591 | End Sub
592 | #tag EndMethod
593 |
594 | #tag Method, Flags = &h21
595 | Private Sub DisplayCustomer(cust As Eddies.Customer)
596 | if cust isa object then
597 | fldFirstName.Text = cust.FirstName
598 | fldLastName.Text = cust.LastName
599 | fldCity.Text = cust.City
600 | fldState.Text = cust.State
601 | fldZip.Text = cust.Zip
602 | fldPhone.Text = cust.Phone
603 | fldEmail.Text = cust.Email
604 | end if
605 |
606 | cvsPhoto.Invalidate
607 |
608 | End Sub
609 | #tag EndMethod
610 |
611 | #tag Method, Flags = &h21
612 | Private Sub RefreshListbox()
613 | lbCustomers.DeleteAllRows
614 |
615 | dim dict as Xojo.Core.Dictionary = msgGetCustomerList.ReturnGetAllCustomers
616 | if dict is nil then
617 | return
618 | end if
619 |
620 | for each entry as Xojo.Core.DictionaryEntry in dict
621 | dim id as text = entry.Key
622 | dim cust as Xojo.Core.Dictionary = entry.Value
623 |
624 | lbCustomers.AddRow id, cust.Value( "LastName" ) + ", " + cust.Value( "FirstName" )
625 | lbCustomers.RowTag( lbCustomers.LastIndex ) = id
626 | next
627 |
628 | lbCustomers.SortedColumn = 0
629 | lbCustomers.Sort
630 |
631 | End Sub
632 | #tag EndMethod
633 |
634 | #tag Method, Flags = &h21
635 | Private Function RowOfCustomerID(id As Text) As Integer
636 | dim lastListIndex as integer = lbCustomers.ListCount - 1
637 | for row as integer = 0 to lastListIndex
638 | dim tag as variant = lbCustomers.RowTag( row )
639 | if ( tag isa Eddies.Customer and Eddies.Customer( tag ).ID = id ) or _
640 | (tag.Type = Variant.TypeText and tag.TextValue = id ) then
641 | return row
642 | end if
643 | next
644 |
645 | return -1
646 |
647 | End Function
648 | #tag EndMethod
649 |
650 |
651 | #tag ComputedProperty, Flags = &h21
652 | #tag Getter
653 | Get
654 | if cbStore.Value then
655 | //
656 | // Using a surrogate
657 | //
658 | if lbCustomers.ListIndex <> -1 and lbCustomers.RowTag( lbCustomers.ListIndex ) isa Eddies.Customer then
659 | return Eddies.Customer( lbCustomers.RowTag( lbCustomers.ListIndex ) )
660 | else
661 | return nil
662 | end if
663 |
664 | else
665 | //
666 | // Using the direct method
667 | //
668 | if msgGetCustomer.IsConnected then
669 | return nil
670 | else
671 | return msgGetCustomer.ReturnGetCustomer
672 | end if
673 | end if
674 |
675 | End Get
676 | #tag EndGetter
677 | Private CurrentCustomer As Eddies.Customer
678 | #tag EndComputedProperty
679 |
680 | #tag Property, Flags = &h21
681 | Private PreviousListIndex As Integer = -1
682 | #tag EndProperty
683 |
684 |
685 | #tag EndWindowCode
686 |
687 | #tag Events msgGetCustomerList
688 | #tag Event
689 | Sub ResponseReceived(url As Text, httpStatus As Integer, payload As Auto)
690 | #pragma unused url
691 | #pragma unused httpStatus
692 | #pragma unused payload
693 |
694 | RefreshListbox
695 |
696 | lblRoundtrip.Text = format( me.RoundTripMs / 1000.0, "#,0.0" ) + " ms"
697 | pwBusy.Visible = msgGetCustomer.IsConnected or smsgGetCustomerSurrogate.IsBusy
698 | End Sub
699 | #tag EndEvent
700 | #tag EndEvents
701 | #tag Events msgGetCustomer
702 | #tag Event
703 | Sub ResponseReceived(url As Text, httpStatus As Integer, payload As Auto)
704 | #pragma unused url
705 | #pragma unused httpStatus
706 | #pragma unused payload
707 |
708 | //
709 | // If we were only using this one message, we could implment the code
710 | // below and be done with it. For this example project, though, since the
711 | // surrogate is there to show off handling of multiple, simultaneous
712 | // messages, we might as well use it for everything.
713 | //
714 |
715 | 'DisplayCustomer me.ReturnGetCustomer
716 | 'lblRoundtrip.Text = format( me.RoundTripMs / 1000.0, "#,0.0" ) + " s"
717 |
718 | End Sub
719 | #tag EndEvent
720 | #tag EndEvents
721 | #tag Events lbCustomers
722 | #tag Event
723 | Sub Change()
724 | if me.ListIndex <> PreviousListIndex then
725 | ClearFields
726 |
727 | if me.ListIndex <> -1 then
728 | dim tag as variant = me.RowTag( me.ListIndex )
729 | dim id as text = if( tag isa Eddies.Customer, Eddies.Customer( tag ).ID, tag.TextValue )
730 |
731 | //
732 | // Use surrogate method?
733 | //
734 | if cbStore.Value then
735 | //
736 | // See if we have the customer already
737 | //
738 | if tag isa Eddies.Customer then
739 | DisplayCustomer Eddies.Customer( tag )
740 | else
741 | dim msg as new Eddies.GetCustomer
742 | msg.ID = id
743 | msg.Send smsgGetCustomerSurrogate
744 | end if
745 |
746 | else
747 | //
748 | // Use direct method
749 | //
750 | msgGetCustomer.Disconnect
751 | msgGetCustomer.ID = id
752 | msgGetCustomer.Send smsgGetCustomerSurrogate
753 | end if
754 | end if
755 |
756 | PreviousListIndex = me.ListIndex
757 | end if
758 |
759 | pwBusy.Visible = msgGetCustomer.IsConnected or smsgGetCustomerSurrogate.IsBusy
760 | End Sub
761 | #tag EndEvent
762 | #tag EndEvents
763 | #tag Events cvsPhoto
764 | #tag Event
765 | Sub Paint(g As Graphics, areas() As REALbasic.Rect)
766 | #pragma unused areas
767 |
768 | dim cust as Eddies.Customer = CurrentCustomer
769 |
770 | if cust isa object and cust.Photo isa object then
771 | g.DrawPicture cust.Photo, 0, 0
772 |
773 | else
774 | g.ClearRect 0, 0, g.Width, g.Height
775 | end if
776 |
777 | End Sub
778 | #tag EndEvent
779 | #tag EndEvents
780 | #tag Events tmrUpdateControls
781 | #tag Event
782 | Sub Action()
783 | dim value as boolean = not( msgGetCustomer.IsConnected or msgGetCustomerList.IsConnected )
784 |
785 | if fldFirstName.Enabled = value then
786 | //
787 | // Nothing to do
788 | //
789 | return
790 | end if
791 |
792 | fldFirstName.Enabled = value
793 | fldLastName.Enabled = value
794 | fldCity.Enabled = value
795 | fldState.Enabled = value
796 | fldZip.Enabled = value
797 | fldPhone.Enabled = value
798 | fldEmail.Enabled = value
799 | cbTaxable.Enabled = value
800 |
801 | End Sub
802 | #tag EndEvent
803 | #tag EndEvents
804 | #tag Events cbStore
805 | #tag Event
806 | Sub Action()
807 | //
808 | // This checkbox will control whether the already-retrieved records
809 | // will be stored in the Listbox. If not, the existing records will be
810 | // cleared.
811 | //
812 | // This is a simple way to contrast the direct method of downloading information
813 | // by dragging a message to the window (msgGetCustomer) vs. using
814 | // the RESTMessageSurrogate_MTC class.
815 | //
816 |
817 | if not me.Value then
818 | //
819 | // Clear any existing records
820 | //
821 | dim lastListIndex as integer = lbCustomers.ListCount - 1
822 | for row as integer = 0 to lastListIndex
823 | dim tag as variant = lbCustomers.RowTag( row )
824 | if tag isa Eddies.Customer then
825 | lbCustomers.RowTag( row ) = Eddies.Customer( tag ).ID
826 | end if
827 | next
828 | end if
829 |
830 | End Sub
831 | #tag EndEvent
832 | #tag EndEvents
833 | #tag Events smsgGetCustomerSurrogate
834 | #tag Event , Description = 546865205245535466756C20736572766572206861732072657475726E6564206120726573706F6E73652E
835 | Sub ResponseReceived(message As RESTMessage_MTC, url As Text, httpStatus As Integer, payload As Auto)
836 | #pragma unused url
837 | #pragma unused httpStatus
838 | #pragma unused payload
839 |
840 | //
841 | // Store the customer if the store checkbox is checked
842 | //
843 |
844 | dim response as Eddies.GetCustomer = Eddies.GetCustomer( message )
845 | dim cust as Eddies.Customer = response.ReturnGetCustomer
846 |
847 | dim row as integer = RowOfCustomerID( cust.ID )
848 |
849 | if cbStore.Value then
850 | lbCustomers.RowTag( row ) = cust
851 | end if
852 |
853 | if row = lbCustomers.ListIndex then
854 | DisplayCustomer cust
855 | end if
856 |
857 | lblRoundtrip.Text = format( response.RoundTripMs / 1000.0, "#,0.0" ) + " s"
858 | pwBusy.Visible = msgGetCustomer.IsConnected or smsgGetCustomerSurrogate.IsBusy
859 | End Sub
860 | #tag EndEvent
861 | #tag EndEvents
862 | #tag ViewBehavior
863 | #tag ViewProperty
864 | Name="BackColor"
865 | Visible=true
866 | Group="Background"
867 | InitialValue="&hFFFFFF"
868 | Type="Color"
869 | #tag EndViewProperty
870 | #tag ViewProperty
871 | Name="Backdrop"
872 | Visible=true
873 | Group="Background"
874 | Type="Picture"
875 | EditorType="Picture"
876 | #tag EndViewProperty
877 | #tag ViewProperty
878 | Name="CloseButton"
879 | Visible=true
880 | Group="Frame"
881 | InitialValue="True"
882 | Type="Boolean"
883 | EditorType="Boolean"
884 | #tag EndViewProperty
885 | #tag ViewProperty
886 | Name="Composite"
887 | Group="OS X (Carbon)"
888 | InitialValue="False"
889 | Type="Boolean"
890 | #tag EndViewProperty
891 | #tag ViewProperty
892 | Name="Frame"
893 | Visible=true
894 | Group="Frame"
895 | InitialValue="0"
896 | Type="Integer"
897 | EditorType="Enum"
898 | #tag EnumValues
899 | "0 - Document"
900 | "1 - Movable Modal"
901 | "2 - Modal Dialog"
902 | "3 - Floating Window"
903 | "4 - Plain Box"
904 | "5 - Shadowed Box"
905 | "6 - Rounded Window"
906 | "7 - Global Floating Window"
907 | "8 - Sheet Window"
908 | "9 - Metal Window"
909 | "11 - Modeless Dialog"
910 | #tag EndEnumValues
911 | #tag EndViewProperty
912 | #tag ViewProperty
913 | Name="FullScreen"
914 | Group="Behavior"
915 | InitialValue="False"
916 | Type="Boolean"
917 | EditorType="Boolean"
918 | #tag EndViewProperty
919 | #tag ViewProperty
920 | Name="FullScreenButton"
921 | Visible=true
922 | Group="Frame"
923 | InitialValue="False"
924 | Type="Boolean"
925 | EditorType="Boolean"
926 | #tag EndViewProperty
927 | #tag ViewProperty
928 | Name="HasBackColor"
929 | Visible=true
930 | Group="Background"
931 | InitialValue="False"
932 | Type="Boolean"
933 | #tag EndViewProperty
934 | #tag ViewProperty
935 | Name="Height"
936 | Visible=true
937 | Group="Size"
938 | InitialValue="400"
939 | Type="Integer"
940 | #tag EndViewProperty
941 | #tag ViewProperty
942 | Name="ImplicitInstance"
943 | Visible=true
944 | Group="Behavior"
945 | InitialValue="True"
946 | Type="Boolean"
947 | EditorType="Boolean"
948 | #tag EndViewProperty
949 | #tag ViewProperty
950 | Name="Interfaces"
951 | Visible=true
952 | Group="ID"
953 | Type="String"
954 | EditorType="String"
955 | #tag EndViewProperty
956 | #tag ViewProperty
957 | Name="LiveResize"
958 | Visible=true
959 | Group="Behavior"
960 | InitialValue="True"
961 | Type="Boolean"
962 | EditorType="Boolean"
963 | #tag EndViewProperty
964 | #tag ViewProperty
965 | Name="MacProcID"
966 | Group="OS X (Carbon)"
967 | InitialValue="0"
968 | Type="Integer"
969 | #tag EndViewProperty
970 | #tag ViewProperty
971 | Name="MaxHeight"
972 | Visible=true
973 | Group="Size"
974 | InitialValue="32000"
975 | Type="Integer"
976 | #tag EndViewProperty
977 | #tag ViewProperty
978 | Name="MaximizeButton"
979 | Visible=true
980 | Group="Frame"
981 | InitialValue="True"
982 | Type="Boolean"
983 | EditorType="Boolean"
984 | #tag EndViewProperty
985 | #tag ViewProperty
986 | Name="MaxWidth"
987 | Visible=true
988 | Group="Size"
989 | InitialValue="32000"
990 | Type="Integer"
991 | #tag EndViewProperty
992 | #tag ViewProperty
993 | Name="MenuBar"
994 | Visible=true
995 | Group="Menus"
996 | Type="MenuBar"
997 | EditorType="MenuBar"
998 | #tag EndViewProperty
999 | #tag ViewProperty
1000 | Name="MenuBarVisible"
1001 | Group="Behavior"
1002 | InitialValue="True"
1003 | Type="Boolean"
1004 | EditorType="Boolean"
1005 | #tag EndViewProperty
1006 | #tag ViewProperty
1007 | Name="MinHeight"
1008 | Visible=true
1009 | Group="Size"
1010 | InitialValue="64"
1011 | Type="Integer"
1012 | #tag EndViewProperty
1013 | #tag ViewProperty
1014 | Name="MinimizeButton"
1015 | Visible=true
1016 | Group="Frame"
1017 | InitialValue="True"
1018 | Type="Boolean"
1019 | EditorType="Boolean"
1020 | #tag EndViewProperty
1021 | #tag ViewProperty
1022 | Name="MinWidth"
1023 | Visible=true
1024 | Group="Size"
1025 | InitialValue="64"
1026 | Type="Integer"
1027 | #tag EndViewProperty
1028 | #tag ViewProperty
1029 | Name="Name"
1030 | Visible=true
1031 | Group="ID"
1032 | Type="String"
1033 | EditorType="String"
1034 | #tag EndViewProperty
1035 | #tag ViewProperty
1036 | Name="Placement"
1037 | Visible=true
1038 | Group="Behavior"
1039 | InitialValue="0"
1040 | Type="Integer"
1041 | EditorType="Enum"
1042 | #tag EnumValues
1043 | "0 - Default"
1044 | "1 - Parent Window"
1045 | "2 - Main Screen"
1046 | "3 - Parent Window Screen"
1047 | "4 - Stagger"
1048 | #tag EndEnumValues
1049 | #tag EndViewProperty
1050 | #tag ViewProperty
1051 | Name="Resizeable"
1052 | Visible=true
1053 | Group="Frame"
1054 | InitialValue="True"
1055 | Type="Boolean"
1056 | EditorType="Boolean"
1057 | #tag EndViewProperty
1058 | #tag ViewProperty
1059 | Name="Super"
1060 | Visible=true
1061 | Group="ID"
1062 | Type="String"
1063 | EditorType="String"
1064 | #tag EndViewProperty
1065 | #tag ViewProperty
1066 | Name="Title"
1067 | Visible=true
1068 | Group="Frame"
1069 | InitialValue="Untitled"
1070 | Type="String"
1071 | #tag EndViewProperty
1072 | #tag ViewProperty
1073 | Name="Visible"
1074 | Visible=true
1075 | Group="Behavior"
1076 | InitialValue="True"
1077 | Type="Boolean"
1078 | EditorType="Boolean"
1079 | #tag EndViewProperty
1080 | #tag ViewProperty
1081 | Name="Width"
1082 | Visible=true
1083 | Group="Size"
1084 | InitialValue="600"
1085 | Type="Integer"
1086 | #tag EndViewProperty
1087 | #tag EndViewBehavior
1088 |
--------------------------------------------------------------------------------
/Harness Projects/Windows Folder/WndMain.xojo_window:
--------------------------------------------------------------------------------
1 | #tag Window
2 | Begin Window WndMain
3 | BackColor = &cFFFFFF00
4 | Backdrop = 0
5 | CloseButton = True
6 | Compatibility = ""
7 | Composite = False
8 | Frame = 0
9 | FullScreen = False
10 | FullScreenButton= False
11 | HasBackColor = False
12 | Height = 82
13 | ImplicitInstance= True
14 | LiveResize = True
15 | MacProcID = 0
16 | MaxHeight = 82
17 | MaximizeButton = False
18 | MaxWidth = 600
19 | MenuBar = 0
20 | MenuBarVisible = True
21 | MinHeight = 82
22 | MinimizeButton = True
23 | MinWidth = 600
24 | Placement = 0
25 | Resizeable = False
26 | Title = "Main"
27 | Visible = True
28 | Width = 600
29 | Begin Label Label1
30 | AutoDeactivate = True
31 | Bold = False
32 | DataField = ""
33 | DataSource = ""
34 | Enabled = True
35 | Height = 20
36 | HelpTag = ""
37 | Index = -2147483648
38 | InitialParent = ""
39 | Italic = False
40 | Left = 20
41 | LockBottom = False
42 | LockedInPosition= False
43 | LockLeft = True
44 | LockRight = False
45 | LockTop = True
46 | Multiline = True
47 | Scope = 0
48 | Selectable = False
49 | TabIndex = 0
50 | TabPanelIndex = 0
51 | Text = "Use the Examples menu above to choose an example."
52 | TextAlign = 1
53 | TextColor = &c00000000
54 | TextFont = "System"
55 | TextSize = 0.0
56 | TextUnit = 0
57 | Top = 20
58 | Transparent = True
59 | Underline = False
60 | Visible = True
61 | Width = 560
62 | End
63 | End
64 | #tag EndWindow
65 |
66 | #tag WindowCode
67 | #tag EndWindowCode
68 |
69 | #tag ViewBehavior
70 | #tag ViewProperty
71 | Name="BackColor"
72 | Visible=true
73 | Group="Background"
74 | InitialValue="&hFFFFFF"
75 | Type="Color"
76 | #tag EndViewProperty
77 | #tag ViewProperty
78 | Name="Backdrop"
79 | Visible=true
80 | Group="Background"
81 | Type="Picture"
82 | EditorType="Picture"
83 | #tag EndViewProperty
84 | #tag ViewProperty
85 | Name="CloseButton"
86 | Visible=true
87 | Group="Frame"
88 | InitialValue="True"
89 | Type="Boolean"
90 | EditorType="Boolean"
91 | #tag EndViewProperty
92 | #tag ViewProperty
93 | Name="Composite"
94 | Group="OS X (Carbon)"
95 | InitialValue="False"
96 | Type="Boolean"
97 | #tag EndViewProperty
98 | #tag ViewProperty
99 | Name="Frame"
100 | Visible=true
101 | Group="Frame"
102 | InitialValue="0"
103 | Type="Integer"
104 | EditorType="Enum"
105 | #tag EnumValues
106 | "0 - Document"
107 | "1 - Movable Modal"
108 | "2 - Modal Dialog"
109 | "3 - Floating Window"
110 | "4 - Plain Box"
111 | "5 - Shadowed Box"
112 | "6 - Rounded Window"
113 | "7 - Global Floating Window"
114 | "8 - Sheet Window"
115 | "9 - Metal Window"
116 | "11 - Modeless Dialog"
117 | #tag EndEnumValues
118 | #tag EndViewProperty
119 | #tag ViewProperty
120 | Name="FullScreen"
121 | Group="Behavior"
122 | InitialValue="False"
123 | Type="Boolean"
124 | EditorType="Boolean"
125 | #tag EndViewProperty
126 | #tag ViewProperty
127 | Name="FullScreenButton"
128 | Visible=true
129 | Group="Frame"
130 | InitialValue="False"
131 | Type="Boolean"
132 | EditorType="Boolean"
133 | #tag EndViewProperty
134 | #tag ViewProperty
135 | Name="HasBackColor"
136 | Visible=true
137 | Group="Background"
138 | InitialValue="False"
139 | Type="Boolean"
140 | #tag EndViewProperty
141 | #tag ViewProperty
142 | Name="Height"
143 | Visible=true
144 | Group="Size"
145 | InitialValue="400"
146 | Type="Integer"
147 | #tag EndViewProperty
148 | #tag ViewProperty
149 | Name="ImplicitInstance"
150 | Visible=true
151 | Group="Behavior"
152 | InitialValue="True"
153 | Type="Boolean"
154 | EditorType="Boolean"
155 | #tag EndViewProperty
156 | #tag ViewProperty
157 | Name="Interfaces"
158 | Visible=true
159 | Group="ID"
160 | Type="String"
161 | EditorType="String"
162 | #tag EndViewProperty
163 | #tag ViewProperty
164 | Name="LiveResize"
165 | Visible=true
166 | Group="Behavior"
167 | InitialValue="True"
168 | Type="Boolean"
169 | EditorType="Boolean"
170 | #tag EndViewProperty
171 | #tag ViewProperty
172 | Name="MacProcID"
173 | Group="OS X (Carbon)"
174 | InitialValue="0"
175 | Type="Integer"
176 | #tag EndViewProperty
177 | #tag ViewProperty
178 | Name="MaxHeight"
179 | Visible=true
180 | Group="Size"
181 | InitialValue="32000"
182 | Type="Integer"
183 | #tag EndViewProperty
184 | #tag ViewProperty
185 | Name="MaximizeButton"
186 | Visible=true
187 | Group="Frame"
188 | InitialValue="True"
189 | Type="Boolean"
190 | EditorType="Boolean"
191 | #tag EndViewProperty
192 | #tag ViewProperty
193 | Name="MaxWidth"
194 | Visible=true
195 | Group="Size"
196 | InitialValue="32000"
197 | Type="Integer"
198 | #tag EndViewProperty
199 | #tag ViewProperty
200 | Name="MenuBar"
201 | Visible=true
202 | Group="Menus"
203 | Type="MenuBar"
204 | EditorType="MenuBar"
205 | #tag EndViewProperty
206 | #tag ViewProperty
207 | Name="MenuBarVisible"
208 | Group="Behavior"
209 | InitialValue="True"
210 | Type="Boolean"
211 | EditorType="Boolean"
212 | #tag EndViewProperty
213 | #tag ViewProperty
214 | Name="MinHeight"
215 | Visible=true
216 | Group="Size"
217 | InitialValue="64"
218 | Type="Integer"
219 | #tag EndViewProperty
220 | #tag ViewProperty
221 | Name="MinimizeButton"
222 | Visible=true
223 | Group="Frame"
224 | InitialValue="True"
225 | Type="Boolean"
226 | EditorType="Boolean"
227 | #tag EndViewProperty
228 | #tag ViewProperty
229 | Name="MinWidth"
230 | Visible=true
231 | Group="Size"
232 | InitialValue="64"
233 | Type="Integer"
234 | #tag EndViewProperty
235 | #tag ViewProperty
236 | Name="Name"
237 | Visible=true
238 | Group="ID"
239 | Type="String"
240 | EditorType="String"
241 | #tag EndViewProperty
242 | #tag ViewProperty
243 | Name="Placement"
244 | Visible=true
245 | Group="Behavior"
246 | InitialValue="0"
247 | Type="Integer"
248 | EditorType="Enum"
249 | #tag EnumValues
250 | "0 - Default"
251 | "1 - Parent Window"
252 | "2 - Main Screen"
253 | "3 - Parent Window Screen"
254 | "4 - Stagger"
255 | #tag EndEnumValues
256 | #tag EndViewProperty
257 | #tag ViewProperty
258 | Name="Resizeable"
259 | Visible=true
260 | Group="Frame"
261 | InitialValue="True"
262 | Type="Boolean"
263 | EditorType="Boolean"
264 | #tag EndViewProperty
265 | #tag ViewProperty
266 | Name="Super"
267 | Visible=true
268 | Group="ID"
269 | Type="String"
270 | EditorType="String"
271 | #tag EndViewProperty
272 | #tag ViewProperty
273 | Name="Title"
274 | Visible=true
275 | Group="Frame"
276 | InitialValue="Untitled"
277 | Type="String"
278 | #tag EndViewProperty
279 | #tag ViewProperty
280 | Name="Visible"
281 | Visible=true
282 | Group="Behavior"
283 | InitialValue="True"
284 | Type="Boolean"
285 | EditorType="Boolean"
286 | #tag EndViewProperty
287 | #tag ViewProperty
288 | Name="Width"
289 | Visible=true
290 | Group="Size"
291 | InitialValue="600"
292 | Type="Integer"
293 | #tag EndViewProperty
294 | #tag EndViewBehavior
295 |
--------------------------------------------------------------------------------
/Harness Projects/Windows Folder/WndSQLFormatter.xojo_window:
--------------------------------------------------------------------------------
1 | #tag Window
2 | Begin Window WndSQLFormatter
3 | BackColor = &cFFFFFF00
4 | Backdrop = 0
5 | CloseButton = True
6 | Compatibility = ""
7 | Composite = False
8 | Frame = 0
9 | FullScreen = False
10 | FullScreenButton= False
11 | HasBackColor = False
12 | Height = 400
13 | ImplicitInstance= True
14 | LiveResize = True
15 | MacProcID = 0
16 | MaxHeight = 32000
17 | MaximizeButton = True
18 | MaxWidth = 32000
19 | MenuBar = 0
20 | MenuBarVisible = True
21 | MinHeight = 64
22 | MinimizeButton = True
23 | MinWidth = 64
24 | Placement = 0
25 | Resizeable = True
26 | Title = "Untitled"
27 | Visible = True
28 | Width = 600
29 | Begin SQLFormatter msgSQLFormatter
30 | DBVendor = 1
31 | DefaultRESTType = "0"
32 | Enabled = True
33 | Index = -2147483648
34 | InputSQL = ""
35 | IsConnected = False
36 | LockedInPosition= False
37 | MessageSerialNumber= ""
38 | RESTType = ""
39 | RoundTripMs = 0.0
40 | RoundTripWithProcessingMs= 0.0
41 | Rspn_Formatted_SQL= ""
42 | Scope = 2
43 | TabPanelIndex = 0
44 | ValidateCertificates= False
45 | End
46 | Begin TextArea fldSQLIn
47 | AcceptTabs = False
48 | Alignment = 0
49 | AutoDeactivate = True
50 | AutomaticallyCheckSpelling= True
51 | BackColor = &cFFFFFF00
52 | Bold = False
53 | Border = True
54 | DataField = ""
55 | DataSource = ""
56 | Enabled = True
57 | Format = ""
58 | Height = 100
59 | HelpTag = ""
60 | HideSelection = True
61 | Index = -2147483648
62 | Italic = False
63 | Left = 20
64 | LimitText = 0
65 | LineHeight = 0.0
66 | LineSpacing = 1.0
67 | LockBottom = False
68 | LockedInPosition= False
69 | LockLeft = True
70 | LockRight = True
71 | LockTop = True
72 | Mask = ""
73 | Multiline = True
74 | ReadOnly = False
75 | Scope = 2
76 | ScrollbarHorizontal= False
77 | ScrollbarVertical= True
78 | Styled = True
79 | TabIndex = 0
80 | TabPanelIndex = 0
81 | TabStop = True
82 | Text = "select category, Count(*) AS ""Number of suppliers"" from suppliers where available_products > 45 group by category;"
83 | TextColor = &c00000000
84 | TextFont = "System"
85 | TextSize = 0.0
86 | TextUnit = 0
87 | Top = 20
88 | Underline = False
89 | UseFocusRing = True
90 | Visible = True
91 | Width = 560
92 | End
93 | Begin PushButton btnFormat
94 | AutoDeactivate = True
95 | Bold = False
96 | ButtonStyle = "0"
97 | Cancel = False
98 | Caption = "Format"
99 | Default = False
100 | Enabled = True
101 | Height = 20
102 | HelpTag = ""
103 | Index = -2147483648
104 | InitialParent = ""
105 | Italic = False
106 | Left = 448
107 | LockBottom = False
108 | LockedInPosition= False
109 | LockLeft = False
110 | LockRight = True
111 | LockTop = True
112 | Scope = 2
113 | TabIndex = 1
114 | TabPanelIndex = 0
115 | TabStop = True
116 | TextFont = "System"
117 | TextSize = 0.0
118 | TextUnit = 0
119 | Top = 132
120 | Underline = False
121 | Visible = True
122 | Width = 132
123 | End
124 | Begin TextArea fldSQLFormatted
125 | AcceptTabs = False
126 | Alignment = 0
127 | AutoDeactivate = True
128 | AutomaticallyCheckSpelling= True
129 | BackColor = &cFFFFFF00
130 | Bold = False
131 | Border = True
132 | DataField = ""
133 | DataSource = ""
134 | Enabled = True
135 | Format = ""
136 | Height = 216
137 | HelpTag = ""
138 | HideSelection = True
139 | Index = -2147483648
140 | Italic = False
141 | Left = 28
142 | LimitText = 0
143 | LineHeight = 0.0
144 | LineSpacing = 1.0
145 | LockBottom = True
146 | LockedInPosition= False
147 | LockLeft = True
148 | LockRight = True
149 | LockTop = True
150 | Mask = ""
151 | Multiline = True
152 | ReadOnly = False
153 | Scope = 2
154 | ScrollbarHorizontal= False
155 | ScrollbarVertical= True
156 | Styled = True
157 | TabIndex = 2
158 | TabPanelIndex = 0
159 | TabStop = True
160 | Text = ""
161 | TextColor = &c00000000
162 | TextFont = "System"
163 | TextSize = 0.0
164 | TextUnit = 0
165 | Top = 164
166 | Underline = False
167 | UseFocusRing = True
168 | Visible = True
169 | Width = 560
170 | End
171 | End
172 | #tag EndWindow
173 |
174 | #tag WindowCode
175 | #tag EndWindowCode
176 |
177 | #tag Events msgSQLFormatter
178 | #tag Event
179 | Sub ResponseReceived(url As Text, httpStatus As Integer, payload As Auto)
180 | #pragma unused url
181 | #pragma unused httpStatus
182 | #pragma unused payload
183 |
184 | fldSQLFormatted.Text = me.Rspn_Formatted_SQL
185 | return
186 | End Sub
187 | #tag EndEvent
188 | #tag EndEvents
189 | #tag Events btnFormat
190 | #tag Event
191 | Sub Action()
192 | msgSQLFormatter.InputSQL = fldSQLIn.Text.ToText
193 | msgSQLFormatter.Send
194 |
195 | End Sub
196 | #tag EndEvent
197 | #tag EndEvents
198 | #tag ViewBehavior
199 | #tag ViewProperty
200 | Name="BackColor"
201 | Visible=true
202 | Group="Background"
203 | InitialValue="&hFFFFFF"
204 | Type="Color"
205 | #tag EndViewProperty
206 | #tag ViewProperty
207 | Name="Backdrop"
208 | Visible=true
209 | Group="Background"
210 | Type="Picture"
211 | EditorType="Picture"
212 | #tag EndViewProperty
213 | #tag ViewProperty
214 | Name="CloseButton"
215 | Visible=true
216 | Group="Frame"
217 | InitialValue="True"
218 | Type="Boolean"
219 | EditorType="Boolean"
220 | #tag EndViewProperty
221 | #tag ViewProperty
222 | Name="Composite"
223 | Group="OS X (Carbon)"
224 | InitialValue="False"
225 | Type="Boolean"
226 | #tag EndViewProperty
227 | #tag ViewProperty
228 | Name="Frame"
229 | Visible=true
230 | Group="Frame"
231 | InitialValue="0"
232 | Type="Integer"
233 | EditorType="Enum"
234 | #tag EnumValues
235 | "0 - Document"
236 | "1 - Movable Modal"
237 | "2 - Modal Dialog"
238 | "3 - Floating Window"
239 | "4 - Plain Box"
240 | "5 - Shadowed Box"
241 | "6 - Rounded Window"
242 | "7 - Global Floating Window"
243 | "8 - Sheet Window"
244 | "9 - Metal Window"
245 | "11 - Modeless Dialog"
246 | #tag EndEnumValues
247 | #tag EndViewProperty
248 | #tag ViewProperty
249 | Name="FullScreen"
250 | Group="Behavior"
251 | InitialValue="False"
252 | Type="Boolean"
253 | EditorType="Boolean"
254 | #tag EndViewProperty
255 | #tag ViewProperty
256 | Name="FullScreenButton"
257 | Visible=true
258 | Group="Frame"
259 | InitialValue="False"
260 | Type="Boolean"
261 | EditorType="Boolean"
262 | #tag EndViewProperty
263 | #tag ViewProperty
264 | Name="HasBackColor"
265 | Visible=true
266 | Group="Background"
267 | InitialValue="False"
268 | Type="Boolean"
269 | #tag EndViewProperty
270 | #tag ViewProperty
271 | Name="Height"
272 | Visible=true
273 | Group="Size"
274 | InitialValue="400"
275 | Type="Integer"
276 | #tag EndViewProperty
277 | #tag ViewProperty
278 | Name="ImplicitInstance"
279 | Visible=true
280 | Group="Behavior"
281 | InitialValue="True"
282 | Type="Boolean"
283 | EditorType="Boolean"
284 | #tag EndViewProperty
285 | #tag ViewProperty
286 | Name="Interfaces"
287 | Visible=true
288 | Group="ID"
289 | Type="String"
290 | EditorType="String"
291 | #tag EndViewProperty
292 | #tag ViewProperty
293 | Name="LiveResize"
294 | Visible=true
295 | Group="Behavior"
296 | InitialValue="True"
297 | Type="Boolean"
298 | EditorType="Boolean"
299 | #tag EndViewProperty
300 | #tag ViewProperty
301 | Name="MacProcID"
302 | Group="OS X (Carbon)"
303 | InitialValue="0"
304 | Type="Integer"
305 | #tag EndViewProperty
306 | #tag ViewProperty
307 | Name="MaxHeight"
308 | Visible=true
309 | Group="Size"
310 | InitialValue="32000"
311 | Type="Integer"
312 | #tag EndViewProperty
313 | #tag ViewProperty
314 | Name="MaximizeButton"
315 | Visible=true
316 | Group="Frame"
317 | InitialValue="True"
318 | Type="Boolean"
319 | EditorType="Boolean"
320 | #tag EndViewProperty
321 | #tag ViewProperty
322 | Name="MaxWidth"
323 | Visible=true
324 | Group="Size"
325 | InitialValue="32000"
326 | Type="Integer"
327 | #tag EndViewProperty
328 | #tag ViewProperty
329 | Name="MenuBar"
330 | Visible=true
331 | Group="Menus"
332 | Type="MenuBar"
333 | EditorType="MenuBar"
334 | #tag EndViewProperty
335 | #tag ViewProperty
336 | Name="MenuBarVisible"
337 | Group="Behavior"
338 | InitialValue="True"
339 | Type="Boolean"
340 | EditorType="Boolean"
341 | #tag EndViewProperty
342 | #tag ViewProperty
343 | Name="MinHeight"
344 | Visible=true
345 | Group="Size"
346 | InitialValue="64"
347 | Type="Integer"
348 | #tag EndViewProperty
349 | #tag ViewProperty
350 | Name="MinimizeButton"
351 | Visible=true
352 | Group="Frame"
353 | InitialValue="True"
354 | Type="Boolean"
355 | EditorType="Boolean"
356 | #tag EndViewProperty
357 | #tag ViewProperty
358 | Name="MinWidth"
359 | Visible=true
360 | Group="Size"
361 | InitialValue="64"
362 | Type="Integer"
363 | #tag EndViewProperty
364 | #tag ViewProperty
365 | Name="Name"
366 | Visible=true
367 | Group="ID"
368 | Type="String"
369 | EditorType="String"
370 | #tag EndViewProperty
371 | #tag ViewProperty
372 | Name="Placement"
373 | Visible=true
374 | Group="Behavior"
375 | InitialValue="0"
376 | Type="Integer"
377 | EditorType="Enum"
378 | #tag EnumValues
379 | "0 - Default"
380 | "1 - Parent Window"
381 | "2 - Main Screen"
382 | "3 - Parent Window Screen"
383 | "4 - Stagger"
384 | #tag EndEnumValues
385 | #tag EndViewProperty
386 | #tag ViewProperty
387 | Name="Resizeable"
388 | Visible=true
389 | Group="Frame"
390 | InitialValue="True"
391 | Type="Boolean"
392 | EditorType="Boolean"
393 | #tag EndViewProperty
394 | #tag ViewProperty
395 | Name="Super"
396 | Visible=true
397 | Group="ID"
398 | Type="String"
399 | EditorType="String"
400 | #tag EndViewProperty
401 | #tag ViewProperty
402 | Name="Title"
403 | Visible=true
404 | Group="Frame"
405 | InitialValue="Untitled"
406 | Type="String"
407 | #tag EndViewProperty
408 | #tag ViewProperty
409 | Name="Visible"
410 | Visible=true
411 | Group="Behavior"
412 | InitialValue="True"
413 | Type="Boolean"
414 | EditorType="Boolean"
415 | #tag EndViewProperty
416 | #tag ViewProperty
417 | Name="Width"
418 | Visible=true
419 | Group="Size"
420 | InitialValue="600"
421 | Type="Integer"
422 | #tag EndViewProperty
423 | #tag EndViewBehavior
424 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Xojo REST Classes
2 |
3 | A REST client framework for Xojo.
4 |
5 | ## General Information
6 |
7 | There is no standard for RESTful servers. As such, creating classes that work with a variety can be tricky and time-consuming, and tend to make you to work directly with JSON or other raw data. This framework attempts to make the job a bit easier by allowing you to create "messages" by subclassing the main class and implementing various events.
8 |
9 | ### Installation
10 |
11 | Open the enclosed harness project and copy-and-paste the REST Resources folder into your own project.
12 |
13 | **Important**: _Do not drag the REST Resources folder directly from the folder into your project._ Xojo won't like it and will probably show all sorts of odd errors.
14 |
15 | ### Basic Use
16 |
17 | At its most basic, you need to create a "message" for each type of interaction with your RESTful server by subclassing `RESTMessage_MTC`. You might create one message that will login, another that will get a list of information, another to save some data. Each message must implement the `GetURLPattern` event (see below) and _should_ implement the `GetRESTType` event.
18 |
19 | If the REST server communicates with JSON, you can create properties in the message that correspond to the object keys. You can also use the `ExcludeFromOutgoingPayload` event to exclude a property or modify the key or value that will be included. In the `CancelSend` event you can cancel the send or change the URL, payload, or MIME type.
20 |
21 | If you expect information back from the server in the form of JSON, you can create properties with the prefix of "Return", e.g., _ReturnSuccess_, _ReturnFirstName_, etc., and the return payload will be parsed into those properties. You can adjust the prefix through the `Options` (see below). You can also use the `IncomingPayloadValueToProperty` event to "massage" a value or store it elsewhere. For example, if you expect an image to be returned as Base64-encoded, you can use that event to decode it, store the resulting image in a _ReturnImage_ property, then return `True` to prevent `RESTMessage_MTC` from processing the value further.
22 |
23 | `RESTMessage_MTC` will attempt to deserialize a JSON object into a class. For example, suppose you expect JSON from the server that looks like this:
24 |
25 | ```json
26 | {
27 | "user" : {
28 | "FirstName" : "John",
29 | "LastName" : "Doe",
30 | "Age" : 33
31 | }
32 | }
33 | ```
34 |
35 | You can create a User class with properties _FirstName As Text_, _LastName As Text_, and _Age As Integer_, then create a property in the message _ReturnUser As User_. The class will automatically create an instance and fill in the properties for you.
36 |
37 | The `ResponseReceived` event will let you know when the server has responded and, if you choose, let you deal with the payload directly.
38 |
39 | There are times when it is not appropriate to have a single instance of a particular message. For example, if you need to save multiple records in a row. In those cases, you can create a `RESTMessageSurrogate_MTC` (see below) instead and send the message through it. The surrogate will raise all the events that the message would as if you had used `AddHandler` to map the message's events.
40 |
41 | ## Details
42 |
43 | This is a more detailed description of the `RESTMessage_MTC` class.
44 |
45 | ### Events
46 |
47 | | Event | Parameters | Return Value | Description |
48 | | ----- | ---------- | :----------: | ----------- |
49 | | CancelSend | ByRef url As Text,
ByRef httpAction As Text,
ByRef payload As Xojo.Core.MemoryBlock,
ByRef payloadMIMEType As Text | Boolean | The last chance to cancel sending the message, or change the URL, HTTP action, payload, or MIME type for the send. Set the payload to nil to avoid any payload. |
50 | | ContinueWaiting | | Boolean | The message has exceeded the time specified in _MessageOptions.TimeoutSeconds_. Return `True` to let it continue waiting for another period. (See _MessageOptions_ below.) |
51 | | Disconnected | | | The socket has disconnected. |
52 | | Error | msg As Text | | Some error has occurred during the connection. |
53 | | ExcludeFromOutgoingPayload | prop As Xojo.Introspection.PropertyInfo,
ByRef propName As Text,
ByRef propValue As Auto | Boolean | A message property is about to be included in the outgoing payload. If it shouldn't be, return `True`. You can also change the property name that will be used as the JSON object key or the value. |
54 | | GetRESTType | | RESTTypes | See The `GetRESTType` Event below. |
55 | | GetURLPattern | | Text | See The `GetURLPattern` Event below. |
56 | | IncomingPayloadValueToProperty | value As Auto,
prop As Xojo.Introspection.PropertyInfo,
hostObject As Object | Boolean | The incoming payload has a value that has been matched to a property of the message or one of the objects in its properties. Return `True` to prevent this value from being processed automatically, i.e., you will process it yourself. |
57 | | ObjectToJSON | o As Object,
typeInfo As Xojo.Introspection.TypeInfo | Auto | An object in one of the message's properties is about to be serialized, but you may prefer to do it yourself. If so, return a `Xojo.Core.Dictionary` or an `Auto()` array. If you do not implement this event or return nil, automatic processing will proceed. |
58 | | ResponseReceived | url As Text,
HTTPStatus As Integer,
payload As Auto | | The server has responded. The _url_ contains the server's URL, `HTTPStatus` the raw code returned by the server, and `payload` as the best form that RESTMesstage\_MTC could convert it into, i.e., `Xojo.Core.MemoryBlock`, `Auto()`, or `Xojo.Core.Dictionary`. |
59 | | Setup | | | The message object has been constructed. This is a good place to set the initial values of properties or _MessageOptions_. |
60 | | SkipIncomingPayloadProcessing | url As Text,
httpStatus As Integer,
ByRef payload As Auto | Boolean | The server has responded with a payload. If you prefer the class not try to automatically parse it, return `True`. |
61 |
62 | ### The `GetURLPattern` Event
63 |
64 | This event will let you specify the URL that will be used to connect to the server. It is raised each time you call `Send`.
65 |
66 | You must return some value here.
67 |
68 | The URL can be complete or may contain placeholders that represent properties within the message. For example, you need to get the weather in the zip code 99911 and the RESTful server requires the URL in the form:
69 |
70 | ```
71 | http://www.someweathersite.com/api/get/zip/99911
72 | ```
73 |
74 | You can create a property in your message subclass, _ZipCode_, and return the URL pattern like this:
75 |
76 | ```
77 | http://www.someweathersite.com/api/get/zip/:ZipCode
78 | ```
79 |
80 | `RESTMessage_MTC` will do the appropriate substitution. To send the message, you merely have to fill in the property and call `Send`.
81 |
82 | __Note__: Properties that are part of the URL pattern will never be included in the outgoing payload.
83 |
84 | ### The `GetRESTType` Event
85 |
86 | `RESTMessage_MTC` defines a _RESTTypes_ enum whose values either include or correspond to HTTP actions. Return the type appropriate for the message. As of v.1.0, these are:
87 |
88 | | Type |
89 | | --------- |
90 | | Unknown |
91 | | Create |
92 | | Read |
93 | | UpdateReplace |
94 | | UpdateModify |
95 | | Authenticate |
96 | | DELETE |
97 | | GET |
98 | | HEAD |
99 | | OPTIONS |
100 | | PATCH |
101 | | POST |
102 | | PUT |
103 |
104 | The uppercase types correspond directly to an HTTP action. The lowercase types are for convenience and will choose the proper action. For example, `Read` corresponds to the `GET` action.
105 |
106 | ### Properties
107 |
108 | | Property | Type | Read Only | Description |
109 | | -------- | ---- | :------: | ------------ |
110 | | DefaultRESTType | RESTTypes | no | The default REST type that will be used of the `GetRestType` event is not implemented. |
111 | | IsConnected | Boolean | __YES__ | Returns `True` if the socket is currently connected. |
112 | | MessageOptions | M\_REST.MessageOptions | no | Set the options for the message. See _MessageOptions_ below. |
113 | | MessageSerialNumber | Int64 | __YES__ | A unique number (within the session) assigned to each new instance of a message. |
114 | | MessageTag | Auto | no | Anything you wish to attach to a message. Does not get transmitted. |
115 | | RESTType | RESTTypes | __YES__ | The REST type that is ultimately used for the message. |
116 | | RoundTripMs | Double | __YES__ | The round-trip time, in milliseconds, from when the connection was initiated until a response received. |
117 | | RoundTripWithProcessingMs | Double | __YES__ | The round-trip time, in milliseconds, from when `Send` was invoked until response processing was finished. |
118 |
119 | ### Methods
120 |
121 | | Method | Parameters | Returns | Description |
122 | | ------ | ---------- | ------- | ----------- |
123 | | Disconnect | | | Disconnect from the server immediately. If not connected, will do nothing. |
124 | | Send | (opt) surrogate As RESTMessageSurrogate\_MTC | | Fill in the properties first, make sure the required events are implemented, then use this to send the message. __Note__: If the socket is already connected to the server, you will get an error. Check the _IsConnected_ property or just call `Disconnect` first.
If a surrogate is specified, incoming events will be raised for this message in it too (see below). |
125 |
126 | ### MessageOptions
127 |
128 | The _MessageOptions_ will let you set certain parameters for the message. For example, if a message is expected to take longer to send or receive or you want to make sure the payload is never sent.
129 |
130 | | Property | Type | Default | Description |
131 | | -------- | :--: | :-----: | ----------- |
132 | | AdjustDatesFromTimeZone | Boolean | False | When encoded dates are sent or received, this determines if the time zone should be honored. If so, the date will be adjusted according to the local time zone. |
133 | | ExpectedTextEncoding | Xojo.Core.TextEncoding | Xojo.Core.TextEncoding.UTF8 | When the payload is received, it is usually as UTF-8. If the server expects or delivers something different, specify that here. |
134 | | ReturnPropertyPrefix | Text | "Return" | Any property in your subclass that starts with this prefix will never be included in the outgoing payload and will be cleared and, if possible, populated by the incoming payload. These properties may be a basic type like String, Text, or Integer, a Dictionary, Auto() array, or an object whose public properties correspond to the incoming JSON object. |
135 | | SendWithPayloadIfAvailable | Boolean | True | For any HTTP action _other_ than GET, the class will attempt to construct and attach a payload using the properties of the message that (1) are not "Return" properties and (2) have not been included in the URL pattern. Set this to `True` to avoid that processing in all cases. |
136 | | TimeoutSeconds | Integer | 5 | Sets how long a message can wait before the `ContinueWaiting` event is raised. |
137 |
138 | ### RESTMessageSurrogate_MTC
139 |
140 | The `RESTMessageSurrogate_MTC` class will act as a stand-in for a message after it is sent. Drag the class to your window and implement its events. When sending a message, use the optional second parameter to specify the surrogate.
141 |
142 | __Note__: Events will be raised in the message first and then in the surrogate, except if an event returns a Boolean, returning `True` in the message will prevent the event from being raised in the surrogate.
143 |
144 | Generally it doesn't make much sense to implement the same event in both the message and a surrogate. The surrogate is there for situations where dragging a single copy of a message to your window does not make sense, e.g., you need to quickly save multiple records in a row.
145 |
146 | The parameters of each event match the parameters of the `RESTMessage_MTC` or `Xojo.Net.HTTPSocket` with the instance of the message as the first parameter in each case. This emulates using `AddHandler` to intercept the message's events.
147 |
148 | You can also use the _RESTMessage\_MTC.MessageTag_ property to further identify an instance of a message.
149 |
150 | The `RESTMessageSurrogate_MTC` has some additional properties and methods.
151 |
152 | #### Methods
153 |
154 | | Method | Parameters | Returns | Description |
155 | | ------ | ---------- | ------- | ----------- |
156 | | DisconnectAll | | | Disconnect all of the outstanding messages |
157 | | DisconnectMessage | msg As RESTMessage\_MTC | | Disconnect a single message |
158 | | OutstandingMessages | | RESTMessage\_MTC() | An array of outstanding messages |
159 |
160 | #### Properties
161 |
162 | | Property | Type | Default | Description |
163 | | -------- | :--: | :-----: | ----------- |
164 | | IsBusy | Boolean | | Returns `True` if there are still outstanding messages |
165 |
166 | ## Contributions
167 |
168 | Contributions to this project are welcome. Fork it to your own repo, then submit changes. However, be forewarned that only those changes that we deem universally useful will be included.
169 |
170 | ## Who Did This?
171 |
172 | This project was designed and implemented by:
173 |
174 | * Kem Tekinay (ktekinay at mactechnologies.com)
175 |
176 | With special thanks to [Advanced Medical Pricing Solutions, Inc.](http://www.advancedpricing.com) for making this possible.
177 |
178 | ## Release Notes
179 |
180 | 1.2 (May 18, 2016)
181 |
182 | - Added `RESTMessageSurrogate_MTC.Sent` event.
183 | - Changed where _ResponseReceivedMicroseconds_ is recorded.
184 | - Changed the parameter _sender_ to _message_ in `RESTMessageSurrogate_MTC` events.
185 |
186 | 1.1 (May 18, 2016)
187 |
188 | - Changed _Options_ property to _MessageOptions_ to prevent possible conflicts in subclasses.
189 | - Added _MessageSerialNumber_ property.
190 | - Added _RoundTripWithProcessingMs_ property.
191 | - Added _MessageTag_ property.
192 | - Added `RESTMessageSurrogate_MTC` class.
193 |
194 | 1.0 (May 12, 2016)
195 |
196 | - Initial release.
197 |
--------------------------------------------------------------------------------
/REST Resources/M_REST.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Module
2 | Protected Module M_REST
3 | #tag Method, Flags = &h21
4 | Private Function GetZeroParamConstructor(ti As Xojo.Introspection.TypeInfo) As Xojo.Introspection.ConstructorInfo
5 | dim constructors() as Xojo.Introspection.ConstructorInfo = ti.Constructors
6 |
7 | //
8 | // Works backwords in the hope that that subclass Constructor if any, is later in the array
9 | //
10 | for i as integer = constructors.Ubound downto 0
11 | dim c as Xojo.Introspection.ConstructorInfo = constructors( i )
12 | try
13 | #pragma BreakOnExceptions false
14 | dim params() as Xojo.Introspection.ParameterInfo = c.Parameters
15 | #pragma BreakOnExceptions default
16 | if params.Ubound = -1 then
17 | return c
18 | end if
19 |
20 | catch err as OutOfBoundsException
21 | //
22 | // A bug in Xojo as of 2016r11 when there is no
23 | // specific Constructor created for the class
24 | // If this exception is raised, we've found the only
25 | // Constructor
26 | return c
27 |
28 | end try
29 | next i
30 |
31 | return nil
32 |
33 | End Function
34 | #tag EndMethod
35 |
36 |
37 | #tag ViewBehavior
38 | #tag ViewProperty
39 | Name="Index"
40 | Visible=true
41 | Group="ID"
42 | InitialValue="-2147483648"
43 | Type="Integer"
44 | #tag EndViewProperty
45 | #tag ViewProperty
46 | Name="Left"
47 | Visible=true
48 | Group="Position"
49 | InitialValue="0"
50 | Type="Integer"
51 | #tag EndViewProperty
52 | #tag ViewProperty
53 | Name="Name"
54 | Visible=true
55 | Group="ID"
56 | Type="String"
57 | #tag EndViewProperty
58 | #tag ViewProperty
59 | Name="Super"
60 | Visible=true
61 | Group="ID"
62 | Type="String"
63 | #tag EndViewProperty
64 | #tag ViewProperty
65 | Name="Top"
66 | Visible=true
67 | Group="Position"
68 | InitialValue="0"
69 | Type="Integer"
70 | #tag EndViewProperty
71 | #tag EndViewBehavior
72 | End Module
73 | #tag EndModule
74 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/ClassMeta.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Private Class ClassMeta
3 | #tag Method, Flags = &h0
4 | Sub Constructor()
5 | ReturnPropertiesDict = new Xojo.Core.Dictionary
6 | SendPropertiesDict = new Xojo.Core.Dictionary
7 | End Sub
8 | #tag EndMethod
9 |
10 |
11 | #tag Property, Flags = &h0
12 | ReturnPropertiesDict As Xojo.Core.Dictionary
13 | #tag EndProperty
14 |
15 | #tag Property, Flags = &h0
16 | SendPropertiesDict As Xojo.Core.Dictionary
17 | #tag EndProperty
18 |
19 |
20 | #tag ViewBehavior
21 | #tag ViewProperty
22 | Name="Index"
23 | Visible=true
24 | Group="ID"
25 | InitialValue="-2147483648"
26 | Type="Integer"
27 | #tag EndViewProperty
28 | #tag ViewProperty
29 | Name="Left"
30 | Visible=true
31 | Group="Position"
32 | InitialValue="0"
33 | Type="Integer"
34 | #tag EndViewProperty
35 | #tag ViewProperty
36 | Name="Name"
37 | Visible=true
38 | Group="ID"
39 | Type="String"
40 | #tag EndViewProperty
41 | #tag ViewProperty
42 | Name="Super"
43 | Visible=true
44 | Group="ID"
45 | Type="String"
46 | #tag EndViewProperty
47 | #tag ViewProperty
48 | Name="Top"
49 | Visible=true
50 | Group="Position"
51 | InitialValue="0"
52 | Type="Integer"
53 | #tag EndViewProperty
54 | #tag EndViewBehavior
55 | End Class
56 | #tag EndClass
57 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/Options.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Protected Class Options
3 | Implements PrivateOptions
4 | #tag Method, Flags = &h0
5 | Sub Constructor()
6 | ExpectedTextEncoding = Xojo.Core.TextEncoding.UTF8
7 | End Sub
8 | #tag EndMethod
9 |
10 | #tag Method, Flags = &h21
11 | Private Sub SetParentMessage(msg As M_REST.RESTMessage_MTC)
12 | if msg <> ParentMessage then
13 | ParentMessage = msg
14 | PrivateMessage( msg ).ClearClassMeta
15 | end if
16 |
17 | End Sub
18 | #tag EndMethod
19 |
20 |
21 | #tag Property, Flags = &h0
22 | AdjustDatesForTimeZone As Boolean
23 | #tag EndProperty
24 |
25 | #tag ComputedProperty, Flags = &h0
26 | #tag Getter
27 | Get
28 | dim result as Xojo.Core.TextEncoding = mExpectedTextEncoding
29 | if result is nil then
30 | result = Xojo.Core.TextEncoding.UTF8
31 | end if
32 |
33 | return result
34 | End Get
35 | #tag EndGetter
36 | #tag Setter
37 | Set
38 | mExpectedTextEncoding = value
39 | End Set
40 | #tag EndSetter
41 | ExpectedTextEncoding As Xojo.Core.TextEncoding
42 | #tag EndComputedProperty
43 |
44 | #tag Property, Flags = &h21
45 | Private mExpectedTextEncoding As Xojo.Core.TextEncoding
46 | #tag EndProperty
47 |
48 | #tag Property, Flags = &h21
49 | Private mParentMessageWR As WeakRef
50 | #tag EndProperty
51 |
52 | #tag Property, Flags = &h21
53 | Attributes( hidden ) Private mReturnPropertyPrefix As Text = "Return"
54 | #tag EndProperty
55 |
56 | #tag ComputedProperty, Flags = &h21
57 | #tag Getter
58 | Get
59 | if mParentMessageWR is nil then
60 | return nil
61 | else
62 | return M_REST.RESTMessage_MTC( mParentMessageWR.Value )
63 | end if
64 |
65 | End Get
66 | #tag EndGetter
67 | #tag Setter
68 | Set
69 | if value is nil then
70 | mParentMessageWR = nil
71 | else
72 | mParentMessageWR = new WeakRef( value )
73 | end if
74 |
75 | End Set
76 | #tag EndSetter
77 | Private ParentMessage As M_REST.RESTMessage_MTC
78 | #tag EndComputedProperty
79 |
80 | #tag ComputedProperty, Flags = &h0
81 | #tag Getter
82 | Get
83 | return mReturnPropertyPrefix
84 |
85 | End Get
86 | #tag EndGetter
87 | #tag Setter
88 | Set
89 | value = value.Trim
90 |
91 | //
92 | // If the prefix has changed, the parent has to regenerate its
93 | // meta
94 | //
95 |
96 | if value <> mReturnPropertyPrefix then
97 | mReturnPropertyPrefix = value
98 | dim parent as RESTMessage_MTC = ParentMessage
99 | if parent isa object then
100 | PrivateMessage( parent ).ClearClassMeta
101 | end if
102 | end if
103 |
104 | End Set
105 | #tag EndSetter
106 | ReturnPropertyPrefix As Text
107 | #tag EndComputedProperty
108 |
109 | #tag Property, Flags = &h0
110 | SendWithPayloadIfAvailable As Boolean = True
111 | #tag EndProperty
112 |
113 | #tag Property, Flags = &h0
114 | TimeoutSeconds As Integer = 5
115 | #tag EndProperty
116 |
117 |
118 | #tag ViewBehavior
119 | #tag ViewProperty
120 | Name="AdjustDatesForTimeZone"
121 | Group="Behavior"
122 | Type="Boolean"
123 | #tag EndViewProperty
124 | #tag ViewProperty
125 | Name="Index"
126 | Visible=true
127 | Group="ID"
128 | InitialValue="-2147483648"
129 | Type="Integer"
130 | #tag EndViewProperty
131 | #tag ViewProperty
132 | Name="Left"
133 | Visible=true
134 | Group="Position"
135 | InitialValue="0"
136 | Type="Integer"
137 | #tag EndViewProperty
138 | #tag ViewProperty
139 | Name="Name"
140 | Visible=true
141 | Group="ID"
142 | Type="String"
143 | #tag EndViewProperty
144 | #tag ViewProperty
145 | Name="ReturnPropertyPrefix"
146 | Group="Behavior"
147 | Type="Text"
148 | #tag EndViewProperty
149 | #tag ViewProperty
150 | Name="SendWithPayloadIfAvailable"
151 | Group="Behavior"
152 | InitialValue="True"
153 | Type="Boolean"
154 | #tag EndViewProperty
155 | #tag ViewProperty
156 | Name="Super"
157 | Visible=true
158 | Group="ID"
159 | Type="String"
160 | #tag EndViewProperty
161 | #tag ViewProperty
162 | Name="TimeoutSeconds"
163 | Group="Behavior"
164 | InitialValue="5"
165 | Type="Integer"
166 | #tag EndViewProperty
167 | #tag ViewProperty
168 | Name="Top"
169 | Visible=true
170 | Group="Position"
171 | InitialValue="0"
172 | Type="Integer"
173 | #tag EndViewProperty
174 | #tag EndViewBehavior
175 | End Class
176 | #tag EndClass
177 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/PrivateMessage.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Interface
2 | Private Interface PrivateMessage
3 | #tag Method, Flags = &h0
4 | Sub ClearClassMeta()
5 |
6 | End Sub
7 | #tag EndMethod
8 |
9 |
10 | #tag ViewBehavior
11 | #tag ViewProperty
12 | Name="Index"
13 | Visible=true
14 | Group="ID"
15 | InitialValue="-2147483648"
16 | Type="Integer"
17 | #tag EndViewProperty
18 | #tag ViewProperty
19 | Name="Left"
20 | Visible=true
21 | Group="Position"
22 | InitialValue="0"
23 | Type="Integer"
24 | #tag EndViewProperty
25 | #tag ViewProperty
26 | Name="Name"
27 | Visible=true
28 | Group="ID"
29 | Type="String"
30 | #tag EndViewProperty
31 | #tag ViewProperty
32 | Name="Super"
33 | Visible=true
34 | Group="ID"
35 | Type="String"
36 | #tag EndViewProperty
37 | #tag ViewProperty
38 | Name="Top"
39 | Visible=true
40 | Group="Position"
41 | InitialValue="0"
42 | Type="Integer"
43 | #tag EndViewProperty
44 | #tag EndViewBehavior
45 | End Interface
46 | #tag EndInterface
47 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/PrivateOptions.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Interface
2 | Private Interface PrivateOptions
3 | #tag Method, Flags = &h0
4 | Sub SetParentMessage(msg As M_REST.RESTMessage_MTC)
5 |
6 | End Sub
7 | #tag EndMethod
8 |
9 |
10 | #tag ViewBehavior
11 | #tag ViewProperty
12 | Name="Index"
13 | Visible=true
14 | Group="ID"
15 | InitialValue="-2147483648"
16 | Type="Integer"
17 | #tag EndViewProperty
18 | #tag ViewProperty
19 | Name="Left"
20 | Visible=true
21 | Group="Position"
22 | InitialValue="0"
23 | Type="Integer"
24 | #tag EndViewProperty
25 | #tag ViewProperty
26 | Name="Name"
27 | Visible=true
28 | Group="ID"
29 | Type="String"
30 | #tag EndViewProperty
31 | #tag ViewProperty
32 | Name="Super"
33 | Visible=true
34 | Group="ID"
35 | Type="String"
36 | #tag EndViewProperty
37 | #tag ViewProperty
38 | Name="Top"
39 | Visible=true
40 | Group="Position"
41 | InitialValue="0"
42 | Type="Integer"
43 | #tag EndViewProperty
44 | #tag EndViewBehavior
45 | End Interface
46 | #tag EndInterface
47 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/PrivateSurrogate.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Interface
2 | Private Interface PrivateSurrogate
3 | #tag Method, Flags = &h0
4 | Sub AppendMessage(msg As M_REST.RESTMessage_MTC)
5 |
6 | End Sub
7 | #tag EndMethod
8 |
9 | #tag Method, Flags = &h0
10 | Function RaiseAuthenticationRequired(message As RESTMessage_MTC, realm As Text, ByRef name As Text, ByRef password As Text) As Boolean
11 |
12 | End Function
13 | #tag EndMethod
14 |
15 | #tag Method, Flags = &h0
16 | Function RaiseContinueWaiting(message As RESTMessage_MTC) As Boolean
17 |
18 | End Function
19 | #tag EndMethod
20 |
21 | #tag Method, Flags = &h0
22 | Sub RaiseDisconnected(message As RESTMessage_MTC)
23 |
24 | End Sub
25 | #tag EndMethod
26 |
27 | #tag Method, Flags = &h0
28 | Sub RaiseError(message As RESTMessage_MTC, msg As Text)
29 |
30 | End Sub
31 | #tag EndMethod
32 |
33 | #tag Method, Flags = &h0
34 | Sub RaiseHeadersReceived(message As RESTMessage_MTC, url As Text, httpStatus As Integer)
35 |
36 | End Sub
37 | #tag EndMethod
38 |
39 | #tag Method, Flags = &h0
40 | Sub RaiseReceiveProgress(message As RESTMessage_MTC, bytesReceived As Int64, totalBytes As Int64, newData As Xojo.Core.MemoryBlock)
41 |
42 | End Sub
43 | #tag EndMethod
44 |
45 | #tag Method, Flags = &h0
46 | Sub RaiseResponseReceived(message As RESTMessage_MTC, url As Text, httpStatus As Integer, payload As Auto)
47 |
48 | End Sub
49 | #tag EndMethod
50 |
51 | #tag Method, Flags = &h0
52 | Sub RaiseSendProgress(message As RESTMessage_MTC, bytesSent As Int64, bytesLeft As Int64)
53 |
54 | End Sub
55 | #tag EndMethod
56 |
57 | #tag Method, Flags = &h0
58 | Sub RaiseSent(message As RESTMessage_MTC)
59 |
60 | End Sub
61 | #tag EndMethod
62 |
63 | #tag Method, Flags = &h0
64 | Sub RemoveMessage(msg As M_REST.RESTMessage_MTC)
65 |
66 | End Sub
67 | #tag EndMethod
68 |
69 |
70 | End Interface
71 | #tag EndInterface
72 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/RESTException.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Protected Class RESTException
3 | Inherits RuntimeException
4 | #tag Method, Flags = &h0
5 | Sub Constructor()
6 |
7 | End Sub
8 | #tag EndMethod
9 |
10 | #tag Method, Flags = &h0
11 | Sub Constructor(reason As Text)
12 | self.Reason = reason
13 | End Sub
14 | #tag EndMethod
15 |
16 |
17 | #tag ViewBehavior
18 | #tag ViewProperty
19 | Name="ErrorNumber"
20 | Group="Behavior"
21 | InitialValue="0"
22 | Type="Integer"
23 | #tag EndViewProperty
24 | #tag ViewProperty
25 | Name="Index"
26 | Visible=true
27 | Group="ID"
28 | InitialValue="-2147483648"
29 | Type="Integer"
30 | #tag EndViewProperty
31 | #tag ViewProperty
32 | Name="Left"
33 | Visible=true
34 | Group="Position"
35 | InitialValue="0"
36 | Type="Integer"
37 | #tag EndViewProperty
38 | #tag ViewProperty
39 | Name="Message"
40 | Group="Behavior"
41 | Type="String"
42 | EditorType="MultiLineEditor"
43 | #tag EndViewProperty
44 | #tag ViewProperty
45 | Name="Name"
46 | Visible=true
47 | Group="ID"
48 | Type="String"
49 | #tag EndViewProperty
50 | #tag ViewProperty
51 | Name="Reason"
52 | Group="Behavior"
53 | Type="Text"
54 | #tag EndViewProperty
55 | #tag ViewProperty
56 | Name="Super"
57 | Visible=true
58 | Group="ID"
59 | Type="String"
60 | #tag EndViewProperty
61 | #tag ViewProperty
62 | Name="Top"
63 | Visible=true
64 | Group="Position"
65 | InitialValue="0"
66 | Type="Integer"
67 | #tag EndViewProperty
68 | #tag EndViewBehavior
69 | End Class
70 | #tag EndClass
71 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/RESTMessageSurrogate_MTC.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Class RESTMessageSurrogate_MTC
3 | Implements PrivateSurrogate
4 | #tag Method, Flags = &h21
5 | Private Sub AppendMessage(msg As M_REST.RESTMessage_MTC)
6 | OutstandingMessagesDict.Value( msg ) = nil
7 |
8 | End Sub
9 | #tag EndMethod
10 |
11 | #tag Method, Flags = &h0
12 | Sub DisconnectAll()
13 | for each entry as Xojo.Core.DictionaryEntry in OutstandingMessagesDict
14 | dim msg as M_REST.RESTMessage_MTC = M_REST.RESTMessage_MTC( entry.Key )
15 | msg.Disconnect
16 | next
17 |
18 | OutstandingMessagesDict.RemoveAll
19 |
20 | End Sub
21 | #tag EndMethod
22 |
23 | #tag Method, Flags = &h0
24 | Sub DisconnectMessage(msg As M_REST.RESTMessage_MTC)
25 | msg.Disconnect
26 |
27 | End Sub
28 | #tag EndMethod
29 |
30 | #tag Method, Flags = &h0
31 | Function OutstandingMessages() As M_REST.RESTMessage_MTC()
32 | dim msgs() as M_REST.RESTMessage_MTC
33 | for each entry as Xojo.Core.DictionaryEntry in OutstandingMessagesDict
34 | msgs.Append M_REST.RESTMessage_MTC( entry.Key )
35 | next
36 |
37 | return msgs
38 |
39 | End Function
40 | #tag EndMethod
41 |
42 | #tag Method, Flags = &h21
43 | Private Function RaiseAuthenticationRequired(message As RESTMessage_MTC, realm As Text, ByRef name As Text, ByRef password As Text) As Boolean
44 | return RaiseEvent AuthenticationRequired( message, realm, name, password )
45 | End Function
46 | #tag EndMethod
47 |
48 | #tag Method, Flags = &h21
49 | Private Function RaiseContinueWaiting(message As RESTMessage_MTC) As Boolean
50 | return RaiseEvent ContinueWaiting( message )
51 | End Function
52 | #tag EndMethod
53 |
54 | #tag Method, Flags = &h21
55 | Private Sub RaiseDisconnected(message As RESTMessage_MTC)
56 | RaiseEvent Disconnected( message )
57 | End Sub
58 | #tag EndMethod
59 |
60 | #tag Method, Flags = &h21
61 | Private Sub RaiseError(message As RESTMessage_MTC, msg As Text)
62 | RaiseEvent Error( message, msg )
63 | End Sub
64 | #tag EndMethod
65 |
66 | #tag Method, Flags = &h21
67 | Private Sub RaiseHeadersReceived(message As RESTMessage_MTC, url As Text, httpStatus As Integer)
68 | RaiseEvent HeadersReceived( message, url, httpStatus )
69 | End Sub
70 | #tag EndMethod
71 |
72 | #tag Method, Flags = &h21
73 | Private Sub RaiseReceiveProgress(message As RESTMessage_MTC, bytesReceived As Int64, totalBytes As Int64, newData As Xojo.Core.MemoryBlock)
74 | RaiseEvent ReceiveProgress( message, bytesReceived, totalBytes, newData )
75 |
76 | End Sub
77 | #tag EndMethod
78 |
79 | #tag Method, Flags = &h21
80 | Private Sub RaiseResponseReceived(message As RESTMessage_MTC, url As Text, httpStatus As Integer, payload As Auto)
81 | RaiseEvent ResponseReceived( message, url, httpStatus, payload )
82 | End Sub
83 | #tag EndMethod
84 |
85 | #tag Method, Flags = &h21
86 | Private Sub RaiseSendProgress(message As RESTMessage_MTC, bytesSent As Int64, bytesLeft As Int64)
87 | RaiseEvent SendProgress( message, bytesSent, bytesLeft )
88 |
89 | End Sub
90 | #tag EndMethod
91 |
92 | #tag Method, Flags = &h21, Description = 546865206D65737361676520686173206265656E2073656E742E
93 | Private Sub RaiseSent(message As RESTMessage_MTC)
94 | RaiseEvent Sent( message )
95 | End Sub
96 | #tag EndMethod
97 |
98 | #tag Method, Flags = &h21
99 | Private Sub RemoveMessage(msg As M_REST.RESTMessage_MTC)
100 | #pragma BreakOnExceptions false
101 | try
102 | OutstandingMessagesDict.Remove msg
103 | catch err as KeyNotFoundException
104 | //
105 | // Already gone, so move on
106 | //
107 | end try
108 | #pragma BreakOnExceptions default
109 |
110 | End Sub
111 | #tag EndMethod
112 |
113 |
114 | #tag Hook, Flags = &h0, Description = 546865206D6573736167652072657175697265732061757468656E7469636174696F6E2E2053657420746865206E616D6520616E642070617373776F72642C207468656E2072657475726E20547275652E
115 | Event AuthenticationRequired(message As RESTMessage_MTC, realm As Text, ByRef name As Text, ByRef password As Text) As Boolean
116 | #tag EndHook
117 |
118 | #tag Hook, Flags = &h0, Description = 546865206D6573736167652068617320657863656564207468652074696D652073657420696E204F7074696F6E732E54696D656F75745365636F6E64732E2052657475726E205472756520746F20616C6C6F7720746865206D65737361676520746F206B6565702077616974696E672E
119 | Event ContinueWaiting(message As RESTMessage_MTC) As Boolean
120 | #tag EndHook
121 |
122 | #tag Hook, Flags = &h0, Description = 54686520736F636B65742068617320646973636F6E6E65637465642E
123 | Event Disconnected(message As RESTMessage_MTC)
124 | #tag EndHook
125 |
126 | #tag Hook, Flags = &h0, Description = 416E206572726F7220686173206F636375727265642E
127 | Event Error(message As RESTMessage_MTC, msg As Text)
128 | #tag EndHook
129 |
130 | #tag Hook, Flags = &h0, Description = 54686520686561646572732063616D65206261636B2066726F6D20746865207365727665722E
131 | Event HeadersReceived(message As RESTMessage_MTC, url As Text, httpStatus As Integer)
132 | #tag EndHook
133 |
134 | #tag Hook, Flags = &h0, Description = 546865207374617473206173206120726573706F6E73652069732072656365697665642E
135 | Event ReceiveProgress(message As RESTMessage_MTC, bytesReceived As Int64, totalBytes As Int64, newData As Xojo.Core.MemoryBlock)
136 | #tag EndHook
137 |
138 | #tag Hook, Flags = &h0, Description = 546865205245535466756C20736572766572206861732072657475726E6564206120726573706F6E73652E
139 | Event ResponseReceived(message As RESTMessage_MTC, url As Text, httpStatus As Integer, payload As Auto)
140 | #tag EndHook
141 |
142 | #tag Hook, Flags = &h0, Description = 546865207374617473206F662061206D657373616765206265696E672073656E742E
143 | Event SendProgress(message As RESTMessage_MTC, bytesSent As Int64, bytesLeft As Int64)
144 | #tag EndHook
145 |
146 | #tag Hook, Flags = &h0, Description = 546865206D65737361676520686173206265656E2073656E742E
147 | Event Sent(message As RESTMessage_MTC)
148 | #tag EndHook
149 |
150 |
151 | #tag ComputedProperty, Flags = &h0
152 | #tag Getter
153 | Get
154 | return OutstandingMessagesDict.Count <> 0
155 | End Get
156 | #tag EndGetter
157 | IsBusy As Boolean
158 | #tag EndComputedProperty
159 |
160 | #tag Property, Flags = &h21
161 | Attributes( hidden ) Private mOutstandingMessagesDict As Xojo.Core.Dictionary
162 | #tag EndProperty
163 |
164 | #tag ComputedProperty, Flags = &h21
165 | #tag Getter
166 | Get
167 | if mOutstandingMessagesDict is nil then
168 | mOutstandingMessagesDict = new Xojo.Core.Dictionary
169 | end if
170 |
171 | return mOutstandingMessagesDict
172 | End Get
173 | #tag EndGetter
174 | Private OutstandingMessagesDict As Xojo.Core.Dictionary
175 | #tag EndComputedProperty
176 |
177 |
178 | #tag ViewBehavior
179 | #tag ViewProperty
180 | Name="Index"
181 | Visible=true
182 | Group="ID"
183 | InitialValue="-2147483648"
184 | Type="Integer"
185 | #tag EndViewProperty
186 | #tag ViewProperty
187 | Name="IsBusy"
188 | Group="Behavior"
189 | Type="Boolean"
190 | #tag EndViewProperty
191 | #tag ViewProperty
192 | Name="Left"
193 | Visible=true
194 | Group="Position"
195 | InitialValue="0"
196 | Type="Integer"
197 | #tag EndViewProperty
198 | #tag ViewProperty
199 | Name="Name"
200 | Visible=true
201 | Group="ID"
202 | Type="String"
203 | #tag EndViewProperty
204 | #tag ViewProperty
205 | Name="Super"
206 | Visible=true
207 | Group="ID"
208 | Type="String"
209 | #tag EndViewProperty
210 | #tag ViewProperty
211 | Name="Top"
212 | Visible=true
213 | Group="Position"
214 | InitialValue="0"
215 | Type="Integer"
216 | #tag EndViewProperty
217 | #tag EndViewBehavior
218 | End Class
219 | #tag EndClass
220 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/RESTMessage_MTC.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Class
2 | Class RESTMessage_MTC
3 | Inherits Xojo.Net.HTTPSocket
4 | Implements PrivateMessage
5 | #tag Event
6 | Function AuthenticationRequired(Realm as Text, ByRef Name as Text, ByRef Password as Text) As Boolean
7 | dim surrogate as M_REST.PrivateSurrogate = MessageSurrogate
8 |
9 | if RaiseEvent AuthenticationRequired( realm, name, password ) or _
10 | ( surrogate isa object and surrogate.RaiseAuthenticationRequired( self, realm, name, password ) ) then
11 | return true
12 | else
13 | return false
14 | end if
15 |
16 | End Function
17 | #tag EndEvent
18 |
19 | #tag Event
20 | Sub Error(err as RuntimeException)
21 | mIsConnected = false
22 |
23 | dim surrogate as M_REST.PrivateSurrogate = MessageSurrogate
24 |
25 | if surrogate isa object then
26 | surrogate.RemoveMessage self
27 | end if
28 |
29 | if err isa Xojo.Net.NetException then
30 | select case err.ErrorNumber
31 | case 102
32 | RaiseEvent Disconnected
33 |
34 | if surrogate isa object then
35 | surrogate.RaiseDisconnected( self )
36 | end if
37 |
38 | case else
39 | RaiseEvent Error( err.Reason )
40 |
41 | if surrogate isa object then
42 | surrogate.RaiseError( self, err.Reason )
43 | end if
44 |
45 | end select
46 |
47 | MessageSurrogate = nil
48 |
49 | else
50 |
51 | MessageSurrogate = nil
52 | raise err
53 |
54 | end if
55 |
56 |
57 | End Sub
58 | #tag EndEvent
59 |
60 | #tag Event
61 | Sub FileReceived(URL as Text, HTTPStatus as Integer, File as xojo.IO.FolderItem)
62 | #pragma unused url
63 | #pragma unused httpStatus
64 | #pragma unused file
65 |
66 | // Do nothing for now
67 | End Sub
68 | #tag EndEvent
69 |
70 | #tag Event
71 | Sub HeadersReceived(URL as Text, HTTPStatus as Integer)
72 | RaiseEvent HeadersReceived( url, httpStatus )
73 |
74 | dim surrogate as M_REST.PrivateSurrogate = MessageSurrogate
75 | if surrogate isa object then
76 | surrogate.RaiseHeadersReceived( self, url, httpStatus )
77 | end if
78 |
79 | End Sub
80 | #tag EndEvent
81 |
82 | #tag Event
83 | Sub PageReceived(URL as Text, HTTPStatus as Integer, Content as xojo.Core.MemoryBlock)
84 | ResponseReceivedMicroseconds = Microseconds
85 |
86 | mIsConnected = false
87 | dim surrogate as M_REST.PrivateSurrogate = MessageSurrogate
88 |
89 | if surrogate isa object then
90 | surrogate.RemoveMessage self
91 | end if
92 |
93 | ClearReturnProperties
94 |
95 | dim payload as Auto = content
96 |
97 | if not SkipIncomingPayloadProcessing( url, httpStatus, payload ) then
98 | payload = ProcessPayload( payload )
99 | end if
100 |
101 | ReceiveFinishedMicroseconds = microseconds
102 | RaiseEvent ResponseReceived url, httpStatus, payload
103 |
104 | //
105 | // NOTE: If the caller no longer exists, you will get a NilObjectException here
106 | //
107 |
108 | if surrogate isa object then
109 | surrogate.RaiseResponseReceived( self, url, httpStatus, payload )
110 | MessageSurrogate = nil
111 | end if
112 |
113 | End Sub
114 | #tag EndEvent
115 |
116 | #tag Event
117 | Sub ReceiveProgress(BytesReceived as Int64, TotalBytes as Int64, NewData as xojo.Core.MemoryBlock)
118 | RaiseEvent ReceiveProgress( bytesReceived, totalBytes, newData )
119 |
120 | dim surrogate as M_REST.PrivateSurrogate = MessageSurrogate
121 | if surrogate isa object then
122 | surrogate.RaiseReceiveProgress( self, bytesReceived, totalBytes, newData )
123 | end if
124 |
125 | End Sub
126 | #tag EndEvent
127 |
128 | #tag Event
129 | Sub SendProgress(BytesSent as Int64, BytesLeft as Int64)
130 | RaiseEvent SendProgress( bytesSent, bytesLeft )
131 |
132 | dim surrogate as M_REST.PrivateSurrogate = MessageSurrogate
133 | if surrogate isa object then
134 | surrogate.RaiseSendProgress( self, bytesSent, bytesLeft )
135 | end if
136 |
137 | End Sub
138 | #tag EndEvent
139 |
140 |
141 | #tag Method, Flags = &h21
142 | Private Sub ClearClassMeta()
143 | if ClassName <> "" and ClassMetaDict isa object and ClassMetaDict.HasKey( ClassName ) then
144 | ClassMetaDict.Remove ClassName
145 | end if
146 |
147 | End Sub
148 | #tag EndMethod
149 |
150 | #tag Method, Flags = &h21
151 | Private Sub ClearReturnProperties()
152 | CreateMeta
153 |
154 | dim meta as M_REST.ClassMeta = MyMeta
155 | if meta is nil or MessageOptions.ReturnPropertyPrefix = "" then
156 | return
157 | end if
158 |
159 | for each entry as Xojo.Core.DictionaryEntry in meta.ReturnPropertiesDict
160 | dim prop as Xojo.Introspection.PropertyInfo = entry.Value
161 | dim propType as text = prop.PropertyType.Name
162 |
163 | if propType = "String()" then
164 | #if not TargetiOS then
165 | dim arr() as string = prop.Value( self )
166 | redim arr( -1 )
167 | #endif
168 |
169 | elseif propType = "Text()" then
170 | dim arr() as text = prop.Value( self )
171 | redim arr( -1 )
172 |
173 | elseif propType = "Double()" then
174 | dim arr() as double = prop.Value( self )
175 | redim arr( -1 )
176 |
177 | elseif propType = "Single()" then
178 | dim arr() as single = prop.Value( self )
179 | redim arr( -1 )
180 |
181 | elseif propType = "Currency()" then
182 | dim arr() as currency
183 | redim arr( -1 )
184 |
185 | elseif propType = "Boolean()" then
186 | dim arr() as boolean = prop.Value( self )
187 | redim arr( -1 )
188 |
189 | elseif propType = "Int8()" then
190 | dim arr() as Int8 = prop.Value( self )
191 | redim arr( -1 )
192 |
193 | elseif propType = "Int16()" then
194 | dim arr() as Int16 = prop.Value( self )
195 | redim arr( -1 )
196 |
197 | elseif propType = "Int32()" then
198 | dim arr() as Int32 = prop.Value( self )
199 | redim arr( -1 )
200 |
201 | elseif propType = "Int64()" then
202 | dim arr() as Int64 = prop.Value( self )
203 | redim arr( -1 )
204 |
205 | elseif propType = "UInt8()" then
206 | dim arr() as UInt8 = prop.Value( self )
207 | redim arr( -1 )
208 |
209 | elseif propType = "UInt16()" then
210 | dim arr() as UInt16 = prop.Value( self )
211 | redim arr( -1 )
212 |
213 | elseif propType = "UInt32()" then
214 | dim arr() as UInt32 = prop.Value( self )
215 | redim arr( -1 )
216 |
217 | elseif propType = "UInt64()" then
218 | dim arr() as UInt64 = prop.Value( self )
219 | redim arr( -1 )
220 |
221 | elseif propType.EndsWith( "()" ) then
222 | //
223 | // Object array
224 | //
225 | dim arr() as object = prop.Value( self )
226 | redim arr( -1 )
227 |
228 | elseif propType = "Text" or propType = "String" then
229 | prop.Value( self ) = ""
230 |
231 | elseif propType.Length > 4 and ( propType.BeginsWith( "Int" ) or propType.BeginsWith( "UInt" ) ) then
232 | prop.Value( self ) = 0
233 |
234 | elseif propType = "Double" or propType = "Single" or propType = "Currency" then
235 | prop.Value( self ) = 0.0
236 |
237 | elseif propType = "Boolean" then
238 | prop.Value( self ) = false
239 |
240 | else
241 | //
242 | // Must be an object
243 | //
244 | prop.Value( self ) = nil
245 |
246 | end if
247 | next
248 | End Sub
249 | #tag EndMethod
250 |
251 | #tag Method, Flags = &h0
252 | Sub Constructor()
253 | // Calling the overridden superclass constructor.
254 | Super.Constructor
255 |
256 | CreateMeta
257 |
258 | TimeoutTimer = new Xojo.Core.Timer
259 | TimeoutTimer.Mode = Xojo.Core.Timer.Modes.Off
260 |
261 | AddHandler TimeoutTimer.Action, WeakAddressOf TimeoutTimer_Action
262 |
263 | RaiseEvent Setup
264 |
265 | End Sub
266 | #tag EndMethod
267 |
268 | #tag Method, Flags = &h21
269 | Private Sub CreateMeta()
270 | if ClassMetaDict is nil then
271 | ClassMetaDict = new Xojo.Core.Dictionary
272 | end if
273 |
274 | dim tiSelf as Xojo.Introspection.TypeInfo = Xojo.Introspection.GetType( self )
275 | ClassName = tiSelf.FullName
276 | dim classMeta as M_REST.ClassMeta = ClassMetaDict.Lookup( className, nil )
277 | if classMeta isa object then
278 | //
279 | // Already done
280 | //
281 | return
282 | end if
283 | classMeta = new M_REST.ClassMeta
284 |
285 | dim tiBase as Xojo.Introspection.TypeInfo = tiSelf.BaseType
286 | while tiBase.BaseType isa Object and tiBase.BaseType.FullName <> "Xojo.Net.HTTPSocket"
287 | tiBase = tiBase.BaseType
288 | wend
289 |
290 | //
291 | // Get or create the meta for the base class
292 | //
293 | dim baseName as text = tiBase.FullName
294 | dim baseMeta as M_REST.ClassMeta = ClassMetaDict.Lookup( baseName, nil )
295 | if baseMeta is nil then
296 | baseMeta = new M_REST.ClassMeta
297 | dim dict as Xojo.Core.Dictionary = baseMeta.SendPropertiesDict
298 |
299 | dim props() as Xojo.Introspection.PropertyInfo = tiBase.Properties
300 | for each prop as Xojo.Introspection.PropertyInfo in props
301 | dim propName as text = prop.Name
302 | if prop.CanRead and prop.IsPublic and not prop.IsShared then
303 | dict.Value( propName ) = prop
304 | end if
305 | next
306 | end if
307 |
308 | //
309 | // Fill out the class meta
310 | //
311 | for each prop as Xojo.Introspection.PropertyInfo in tiSelf.Properties
312 | dim propName as text = prop.Name
313 |
314 | if prop.IsShared or not prop.IsPublic then
315 | //
316 | // Doesn't qualify
317 | //
318 | continue for prop
319 | end if
320 |
321 | if baseMeta.SendPropertiesDict.HasKey( propName ) or baseMeta.ReturnPropertiesDict.HasKey( propName ) then
322 | //
323 | // Part of the base so we ignore it
324 | //
325 | continue for prop
326 | end if
327 |
328 | if propName = "Index" then
329 | //
330 | // Something that comes up in a window, so ignore it
331 | //
332 | continue for prop
333 | end if
334 |
335 | dim isReturnProp as boolean
336 |
337 | dim returnPropPrefix as text = MessageOptions.ReturnPropertyPrefix
338 | dim prefixLength as integer = returnPropPrefix.Length
339 | if returnPropPrefix = "" or _ // Can be empty
340 | ( propName.Length > prefixLength and propName.Left( prefixLength ) = returnPropPrefix ) then // Return property
341 | if prop.CanWrite then
342 | classMeta.ReturnPropertiesDict.Value( propName ) = prop
343 | isReturnProp = true
344 | end if
345 | end if
346 |
347 | if not isReturnProp or returnPropPrefix = "" then // Send property
348 | if prop.CanRead then
349 | classMeta.SendPropertiesDict.Value( propName ) = prop
350 | end if
351 | end if
352 | next prop
353 |
354 | classMetaDict.Value( className ) = classMeta
355 |
356 | End Sub
357 | #tag EndMethod
358 |
359 | #tag Method, Flags = &h21
360 | Private Function CreateOutgoingPayload(props() As Xojo.Introspection.PropertyInfo) As Xojo.Core.MemoryBlock
361 | dim result as Xojo.Core.MemoryBlock
362 |
363 | dim json as new Xojo.Core.Dictionary
364 |
365 | for each prop as Xojo.Introspection.PropertyInfo in props
366 | dim propName as text = prop.Name
367 | dim propValue as auto = prop.Value( self )
368 |
369 | if not RaiseEvent ExcludeFromOutgoingPayload( prop, propName, propValue ) then
370 | json.Value( propName ) = Serialize( propValue )
371 | end if
372 | next
373 |
374 | if json.Count <> 0 then
375 | dim t as text = Xojo.Data.GenerateJSON( json )
376 | dim encoding as Xojo.Core.TextEncoding = MessageOptions.ExpectedTextEncoding
377 | result = encoding.ConvertTextToData( t )
378 | end if
379 |
380 | return result
381 |
382 | End Function
383 | #tag EndMethod
384 |
385 | #tag Method, Flags = &h21
386 | Private Function Deserialize(value As Auto, intoProp As Xojo.Introspection.PropertyInfo, currentValue As Auto) As Auto
387 | dim tiDestination as Xojo.Introspection.TypeInfo = intoProp.PropertyType
388 | dim typeName as text = tiDestination.Name
389 |
390 | if typeName.Length > 2 and typeName.EndsWith( "()" ) then
391 | return DeserializeArray( value, intoProp, currentValue )
392 |
393 | elseif IsIntrinsicType( typeName ) then
394 | return value
395 |
396 | else
397 | dim objectDict as Xojo.Core.Dictionary = value
398 | return DeserializeObject( objectDict, intoProp )
399 |
400 | end if
401 | End Function
402 | #tag EndMethod
403 |
404 | #tag Method, Flags = &h21
405 | Private Function DeserializeArray(value As Auto, intoProp As Xojo.Introspection.PropertyInfo, existingArray As Auto) As Auto
406 | dim tiDestination as Xojo.Introspection.TypeInfo = intoProp.PropertyType
407 | dim typeName as text = tiDestination.Name
408 |
409 | dim sourceArr() as auto = value
410 |
411 | select case typeName
412 | case "Text()"
413 | dim arr() as text
414 | try
415 | redim arr( sourceArr.Ubound )
416 | for i as integer = 0 to sourceArr.Ubound
417 | arr( i ) = sourceArr( i )
418 | next
419 | catch err as TypeMismatchException
420 | redim arr( -1 )
421 | end try
422 | return arr
423 |
424 | case "String()"
425 | #if not TargetiOS then
426 | dim arr() as string
427 | try
428 | redim arr( sourceArr.Ubound )
429 | for i as integer = 0 to sourceArr.Ubound
430 | arr( i ) = sourceArr( i )
431 | next
432 | catch err as TypeMismatchException
433 | redim arr( -1 )
434 | end try
435 | return arr
436 | #endif
437 |
438 | case "Boolean()"
439 | dim arr() as boolean
440 | try
441 | redim arr( sourceArr.Ubound )
442 | for i as integer = 0 to sourceArr.Ubound
443 | arr( i ) = sourceArr( i )
444 | next
445 | catch err as TypeMismatchException
446 | redim arr( -1 )
447 | end try
448 | return arr
449 |
450 | case "Currency()"
451 | dim arr() as currency
452 | try
453 | redim arr( sourceArr.Ubound )
454 | for i as integer = 0 to sourceArr.Ubound
455 | arr( i ) = sourceArr( i )
456 | next
457 | catch err as TypeMismatchException
458 | redim arr( -1 )
459 | end try
460 | return arr
461 |
462 | case "Double()"
463 | dim arr() as double
464 | try
465 | redim arr( sourceArr.Ubound )
466 | for i as integer = 0 to sourceArr.Ubound
467 | arr( i ) = sourceArr( i )
468 | next
469 | catch err as TypeMismatchException
470 | redim arr( -1 )
471 | end try
472 | return arr
473 |
474 | case "Single()"
475 | dim arr() as single
476 | try
477 | redim arr( sourceArr.Ubound )
478 | for i as integer = 0 to sourceArr.Ubound
479 | arr( i ) = sourceArr( i )
480 | next
481 | catch err as TypeMismatchException
482 | redim arr( -1 )
483 | end try
484 | return arr
485 |
486 | case "Int8()"
487 | dim arr() as Int8
488 | try
489 | redim arr( sourceArr.Ubound )
490 | for i as integer = 0 to sourceArr.Ubound
491 | arr( i ) = sourceArr( i )
492 | next
493 | catch err as TypeMismatchException
494 | redim arr( -1 )
495 | end try
496 | return arr
497 |
498 | case "Int16()"
499 | dim arr() as Int16
500 | try
501 | redim arr( sourceArr.Ubound )
502 | for i as integer = 0 to sourceArr.Ubound
503 | arr( i ) = sourceArr( i )
504 | next
505 | catch err as TypeMismatchException
506 | redim arr( -1 )
507 | end try
508 | return arr
509 |
510 | case "Int32()"
511 | dim arr() as Int32
512 | try
513 | redim arr( sourceArr.Ubound )
514 | for i as integer = 0 to sourceArr.Ubound
515 | arr( i ) = sourceArr( i )
516 | next
517 | catch err as TypeMismatchException
518 | redim arr( -1 )
519 | end try
520 | return arr
521 |
522 | case "Int64()"
523 | dim arr() as Int64
524 | try
525 | redim arr( sourceArr.Ubound )
526 | for i as integer = 0 to sourceArr.Ubound
527 | arr( i ) = sourceArr( i )
528 | next
529 | catch err as TypeMismatchException
530 | redim arr( -1 )
531 | end try
532 | return arr
533 |
534 | case "Byte()"
535 | dim arr() as byte
536 | try
537 | redim arr( sourceArr.Ubound )
538 | for i as integer = 0 to sourceArr.Ubound
539 | arr( i ) = sourceArr( i )
540 | next
541 | catch err as TypeMismatchException
542 | redim arr( -1 )
543 | end try
544 | return arr
545 |
546 | case "UInt8()"
547 | dim arr() as UInt8
548 | try
549 | redim arr( sourceArr.Ubound )
550 | for i as integer = 0 to sourceArr.Ubound
551 | arr( i ) = sourceArr( i )
552 | next
553 | catch err as TypeMismatchException
554 | redim arr( -1 )
555 | end try
556 | return arr
557 |
558 | case "UInt16()"
559 | dim arr() as UInt16
560 | try
561 | redim arr( sourceArr.Ubound )
562 | for i as integer = 0 to sourceArr.Ubound
563 | arr( i ) = sourceArr( i )
564 | next
565 | catch err as TypeMismatchException
566 | redim arr( -1 )
567 | end try
568 | return arr
569 |
570 | case "UInt32()"
571 | dim arr() as UInt32
572 | try
573 | redim arr( sourceArr.Ubound )
574 | for i as integer = 0 to sourceArr.Ubound
575 | arr( i ) = sourceArr( i )
576 | next
577 | catch err as TypeMismatchException
578 | redim arr( -1 )
579 | end try
580 | return arr
581 |
582 | case "UInt64()"
583 | dim arr() as UInt64
584 | try
585 | redim arr( sourceArr.Ubound )
586 | for i as integer = 0 to sourceArr.Ubound
587 | arr( i ) = sourceArr( i )
588 | next
589 | catch err as TypeMismatchException
590 | redim arr( -1 )
591 | end try
592 | return arr
593 |
594 | case "Integer()"
595 | dim arr() as integer
596 | try
597 | redim arr( sourceArr.Ubound )
598 | for i as integer = 0 to sourceArr.Ubound
599 | arr( i ) = sourceArr( i )
600 | next
601 | catch err as TypeMismatchException
602 | redim arr( -1 )
603 | end try
604 | return arr
605 |
606 | case "Auto()"
607 | return value
608 |
609 | case "Variant()"
610 | #if not TargetiOS then
611 | dim arr() as variant
612 | redim arr( sourceArr.Ubound )
613 | for i as integer = 0 to sourceArr.Ubound
614 | arr( i ) = sourceArr( i )
615 | next
616 | return arr
617 | #endif
618 |
619 | case else
620 | //
621 | // Must be an object
622 | //
623 | dim arr() as object
624 | try
625 | arr = existingArray
626 | redim arr( sourceArr.Ubound )
627 |
628 | for i as integer = 0 to sourceArr.Ubound
629 | arr( i ) = Deserialize( sourceArr( i ), intoProp, existingArray )
630 | next
631 | catch err as TypeMismatchException
632 | redim arr( -1 )
633 | end try
634 | return arr
635 |
636 | end select
637 | End Function
638 | #tag EndMethod
639 |
640 | #tag Method, Flags = &h21
641 | Private Function DeserializeDate(value As Text, intoProp As Xojo.Introspection.PropertyInfo) As Auto
642 | //
643 | // We are expecting the ISO 8601 format
644 | // as a date or date and time.
645 | //
646 | // https://en.wikipedia.org/wiki/ISO_8601
647 | //
648 |
649 | dim parts() as text = value.Split( "T" )
650 | if parts.Ubound = -1 or parts.Ubound > 1 then
651 | //
652 | // We don't recognize this format
653 | //
654 | return nil
655 | end if
656 |
657 | dim datePart as text = parts( 0 )
658 | dim dateParts() as text = datePart.Split( "-" )
659 | if dateParts.Ubound <> 2 then
660 | return nil
661 | end if
662 |
663 | dim year as integer = Integer.FromText( dateParts( 0 ) )
664 | dim month as integer = Integer.FromText( dateParts( 1 ) )
665 | dim day as integer = Integer.FromText( dateParts( 2 ) )
666 |
667 | //
668 | // See if there is a time
669 | //
670 | dim hour as integer
671 | dim minute as integer
672 | dim second as integer
673 |
674 | dim tz as Xojo.Core.TimeZone = Xojo.Core.TimeZone.Current
675 | dim tzHours as double = tz.SecondsFromGMT / 3600.0
676 |
677 | if parts.Ubound = 1 then
678 | dim timePart as text = parts( 1 )
679 | dim timeParts() as text
680 | dim tzPart as text
681 |
682 | select case true
683 | case timePart.IndexOf( "Z" ) <> -1
684 | timeParts = timePart.Split( "Z" )
685 | timePart = timeParts( 0 )
686 | tzPart = "0"
687 |
688 | case timePart.IndexOf( "-" ) <> -1
689 | timeParts = timePart.Split( "-" )
690 | timePart = timeParts( 0 )
691 | tzPart = "-" + timeParts( 1 )
692 |
693 | case timePart.IndexOf( "+" ) <> -1
694 | timeParts = timePart.Split( "+" )
695 | timePart = timeParts( 0 )
696 | tzPart = timeParts( 1 )
697 |
698 | end select
699 |
700 | //
701 | // The time will either be in HH:MM:SS format or HHMMSS format
702 | //
703 | timePart = timePart.ReplaceAll( ":", "" )
704 | if timePart.Length = 6 then
705 | hour = Integer.FromText( timePart.Left( 2 ) )
706 | minute = Integer.FromText( timePart.Mid( 2, 2 ) )
707 | second = Integer.FromText( timePart.Right( 2 ) )
708 |
709 | //
710 | // Process the timezone, maybe
711 | //
712 | if MessageOptions.AdjustDatesForTimeZone then
713 | dim tzParts() as text = tzPart.Split( ":" )
714 | if tzParts.Ubound = 1 then
715 | tzHours = Integer.FromText( tzParts( 0 ) ) + ( Integer.FromText( tzParts( 1 ) ) / 60.0 )
716 | tz = new Xojo.Core.TimeZone( tzHours * 3600.0 )
717 | end if
718 | end if
719 |
720 | end if
721 | end if
722 |
723 | //
724 | // Create the object
725 | //
726 | select case intoProp.PropertyType.FullName
727 | case "Xojo.Core.Date"
728 | dim d as new Xojo.Core.Date( year, month, day, hour, minute, second, 0, tz )
729 | return d
730 |
731 | case else
732 | #if not TargetiOS then
733 | dim d as new Date( year, month, day, hour, minute, second, tzHours )
734 | return d
735 | #endif
736 |
737 | end select
738 | End Function
739 | #tag EndMethod
740 |
741 | #tag Method, Flags = &h21
742 | Private Function DeserializeDictionary(value As Xojo.Core.Dictionary, intoProp As Xojo.Introspection.PropertyInfo) As Auto
743 | select case intoProp.PropertyType.FullName
744 | case "Xojo.Core.Dictionary"
745 | dim dict as new Xojo.Core.Dictionary
746 | for each entry as Xojo.Core.DictionaryEntry in value
747 | dict.Value( entry.Key ) = entry.Value
748 | next
749 | return dict
750 |
751 | case "Dictionary"
752 | #if not TargetiOS then
753 | dim dict as new Dictionary
754 | for each entry as Xojo.Core.DictionaryEntry in value
755 | dict.Value( entry.Key ) = entry.Value
756 | next
757 | return dict
758 | #endif
759 |
760 | end select
761 | End Function
762 | #tag EndMethod
763 |
764 | #tag Method, Flags = &h21
765 | Private Function DeserializeObject(value As Auto, intoProp As Xojo.Introspection.PropertyInfo) As Object
766 | dim tiObject as Xojo.Introspection.TypeInfo = intoProp.PropertyType
767 | dim typeName as text = tiObject.Name
768 |
769 | select case typeName
770 | case "Dictionary", "Xojo.Core.Dictionary"
771 | return DeserializeDictionary( value, intoProp )
772 |
773 | case "Date", "Xojo.Core.Date"
774 | return DeserializeDate( value, intoProp )
775 |
776 | case else
777 | //
778 | // Have to create a new object to return
779 | //
780 | dim c as Xojo.Introspection.ConstructorInfo = GetZeroParamConstructor( intoProp.PropertyType )
781 | if c isa object then
782 | dim o as object = c.Invoke
783 |
784 | //
785 | // Create a dictionary of the object's properties
786 | //
787 | dim propsDict as new Xojo.Core.Dictionary
788 | for each prop as Xojo.Introspection.PropertyInfo in tiObject.Properties
789 | if prop.CanWrite and prop.IsPublic and not prop.IsShared then
790 | propsDict.Value( prop.Name ) = prop
791 | end if
792 | next prop
793 |
794 | if propsDict.Count <> 0 then
795 | JSONObjectToProps( value, propsDict, "", o )
796 | end if
797 |
798 | return o
799 | end if
800 | end select
801 | End Function
802 | #tag EndMethod
803 |
804 | #tag Method, Flags = &h21
805 | Private Sub Destructor()
806 | if TimeoutTimer isa Object then
807 | TimeoutTimer.Mode = Xojo.Core.Timer.Modes.Off
808 | RemoveHandler TimeoutTimer.Action, WeakAddressOf TimeoutTimer_Action
809 | TimeoutTimer = nil
810 | end if
811 |
812 | //
813 | // We don't bother removing the message from the MessageSurrogate here.
814 | // Why? Well, if the surrogate still has the message, this
815 | // Destructor will never fire anyway.
816 | //
817 | End Sub
818 | #tag EndMethod
819 |
820 | #tag Method, Flags = &h0
821 | Sub Disconnect()
822 | if IsConnected then
823 | mIsConnected = false
824 | TimeoutTimer.Mode = Xojo.Core.Timer.Modes.Off
825 | super.Disconnect
826 | end if
827 |
828 | dim surrogate as M_REST.PrivateSurrogate = MessageSurrogate
829 | if surrogate isa object then
830 | surrogate.RemoveMessage self
831 | MessageSurrogate = nil
832 | end if
833 |
834 |
835 | End Sub
836 | #tag EndMethod
837 |
838 | #tag Method, Flags = &h21
839 | Private Shared Function IsIntrinsicType(propType As Text) As Boolean
840 | static types() as text
841 |
842 | if types.Ubound = -1 then
843 | types = array( _
844 | "Int8", "Int16", "Int32", "Int64", _
845 | "Byte", "UInt8", "UInt16", "UInt32", "UInt64", _
846 | "Single", "Double", "Currency", _
847 | "String", "Text", _
848 | "Boolean" _
849 | )
850 |
851 | //
852 | // Add the array versions
853 | //
854 | dim lastIndex as integer = types.Ubound
855 | for i as integer = 0 to lastIndex
856 | types.Append types( i ) + "()"
857 | next
858 | end if
859 |
860 | return types.IndexOf( propType ) <> -1
861 |
862 | End Function
863 | #tag EndMethod
864 |
865 | #tag Method, Flags = &h21
866 | Private Sub JSONObjectToProps(json As Xojo.Core.Dictionary, propsDict As Xojo.Core.Dictionary, propPrefix As Text, hostObject As Object)
867 | for each entry as Xojo.Core.DictionaryEntry in json
868 | dim returnPropName as text = propPrefix + entry.Key
869 | if not propsDict.HasKey( returnPropName ) then
870 | continue for entry
871 | end if
872 |
873 | dim prop as Xojo.Introspection.PropertyInfo = propsDict.Value( returnPropName )
874 |
875 | dim value as Auto = entry.Value
876 |
877 | if not RaiseEvent IncomingPayloadValueToProperty( value, prop, hostObject ) then
878 | try
879 | value = Deserialize( value, prop, prop.Value( hostObject ) )
880 | prop.Value( hostObject ) = value
881 |
882 | catch err as TypeMismatchException
883 | //
884 | // Didn't work, move on
885 | //
886 | end try
887 |
888 | end if
889 | next
890 |
891 | End Sub
892 | #tag EndMethod
893 |
894 | #tag Method, Flags = &h21
895 | Private Sub PrepareToSend()
896 | mIsConnected = true
897 | RequestSentMicroseconds = Microseconds
898 | ResponseReceivedMicroseconds = -1.0
899 |
900 | TimeoutTimer.Period = MessageOptions.TimeOutSeconds * 1000
901 | TimeoutTimer.Mode = Xojo.Core.Timer.Modes.Multiple
902 |
903 | End Sub
904 | #tag EndMethod
905 |
906 | #tag Method, Flags = &h21
907 | Private Function ProcessImagePayload(payload As Xojo.Core.MemoryBlock) As Auto
908 | dim result as Auto
909 |
910 | #if TargetiOS then
911 | #pragma error "Finish this!"
912 |
913 | #else
914 |
915 | //
916 | // Have to use the classic MemoryBlock
917 | //
918 | dim mbTemp as MemoryBlock = payload.Data
919 | dim p as Picture = Picture.FromData( mbTemp.StringValue( 0, payload.Size ) )
920 | result = p
921 |
922 | #endif
923 |
924 | if result <> nil then
925 | //
926 | // It's got something, so let's try to store it
927 | //
928 |
929 | dim meta as M_REST.ClassMeta = MyMeta
930 | dim tiResult as Xojo.Introspection.TypeInfo = Xojo.Introspection.GetType( result )
931 | dim matchType as text = tiResult.Name
932 |
933 | dim picProps() as Xojo.Introspection.PropertyInfo
934 |
935 | for each entry as Xojo.Core.DictionaryEntry in meta.ReturnPropertiesDict
936 | dim prop as Xojo.Introspection.PropertyInfo = entry.Value
937 | if prop.PropertyType.Name = matchType then
938 | picProps.Append prop
939 | end if
940 | next
941 |
942 | if picProps.Ubound = 0 then
943 | picProps( 0 ).Value( self ) = result
944 | end if
945 | end if
946 |
947 | return result
948 |
949 | End Function
950 | #tag EndMethod
951 |
952 | #tag Method, Flags = &h21
953 | Private Sub ProcessJSONPayload(payload As Auto)
954 | CreateMeta // REALLY shouldn't be needed, but let's make sure
955 |
956 | dim returnProps as Xojo.Core.Dictionary = MyMeta.ReturnPropertiesDict
957 |
958 | //
959 | // If the JSON is just an array, see if there is only one return property
960 | // and it's an array. If so, copy the items into that.
961 | //
962 |
963 | dim tiPayload as Xojo.Introspection.TypeInfo = Xojo.Introspection.GetType( payload )
964 | if tiPayload.Name.Length > 2 and tiPayload.Name.EndsWith( "()" ) then
965 |
966 | if returnProps.Count = 1 then
967 | dim prop as Xojo.Introspection.PropertyInfo
968 | for each entry as Xojo.Core.DictionaryEntry in returnProps
969 | prop = entry.Value
970 | next
971 |
972 | try
973 | prop.Value( self ) = DeserializeArray( payload, prop, prop.Value( self ) )
974 | catch err as TypeMismatchException
975 | //
976 | // Oh well, we tried
977 | //
978 | end try
979 | end if
980 |
981 | else
982 | //
983 | // It's an object, so it will be case-sensitive.
984 | // Cycle through the object and match it against the returnProps
985 | // dictionary that is not case-sensitive
986 | //
987 |
988 | dim json as Xojo.Core.Dictionary = payload
989 | dim returnPropPrefix as text = MessageOptions.ReturnPropertyPrefix
990 | JSONObjectToProps( json, returnProps, returnPropPrefix, self )
991 |
992 | end if
993 | End Sub
994 | #tag EndMethod
995 |
996 | #tag Method, Flags = &h21
997 | Private Function ProcessPayload(payload As Xojo.Core.MemoryBlock) As Auto
998 | dim result as Auto
999 |
1000 | dim indicatedContentType as text = self.ResponseHeader( "Content-Type" )
1001 |
1002 | dim parts() as text = indicatedContentType.Split( "/" )
1003 | dim indicatedType as text = if( parts.Ubound <> -1, parts( 0 ), "" )
1004 | dim indicatedSubtype as text = if( parts.Ubound > 0, indicatedContentType.Mid( indicatedContentType.IndexOf( "/" ) + 1 ), "" )
1005 |
1006 | if indicatedType = "image" then
1007 | try
1008 | result = ProcessImagePayload( payload )
1009 | catch err as RuntimeException
1010 | if err isa EndException or err isa ThreadEndException then
1011 | raise err
1012 | end if
1013 | indicatedType = ""
1014 | indicatedSubtype = ""
1015 | end try
1016 | end if
1017 |
1018 | if indicatedType = "text" or _
1019 | ( indicatedSubtype.Length >= 4 and indicatedSubtype.BeginsWith( "json" ) ) or _
1020 | ( indicatedSubtype.Length >= 3 and indicatedSubtype.BeginsWith( "xml" ) ) or _
1021 | indicatedType = "" then
1022 | try
1023 | result = ProcessTextPayload( payload, indicatedSubtype )
1024 | catch err as RuntimeException
1025 | if err isa EndException or err isa ThreadEndException then
1026 | raise err
1027 | end if
1028 | indicatedType = ""
1029 | indicatedSubtype = ""
1030 | end try
1031 | end if
1032 |
1033 | if result = nil then
1034 | //
1035 | // The indicated type was wrong or couldn't be handled properly.
1036 | // In either case, just pass it on.
1037 | //
1038 | result = payload
1039 | end if
1040 |
1041 | return result
1042 |
1043 |
1044 | End Function
1045 | #tag EndMethod
1046 |
1047 | #tag Method, Flags = &h21
1048 | Private Function ProcessTextPayload(payload As Xojo.Core.MemoryBlock, subtype As Text) As Auto
1049 | dim result as Auto
1050 |
1051 | dim encoding as Xojo.Core.TextEncoding = MessageOptions.ExpectedTextEncoding
1052 |
1053 | //
1054 | // See if an encoding is indicated
1055 | //
1056 | if subtype <> "" then
1057 | dim parts() as text = subtype.Split( ";" )
1058 | if parts.Ubound > 0 then
1059 |
1060 | dim pairs as new Xojo.Core.Dictionary
1061 | for each part as text in parts
1062 | dim subparts() as text = part.Split( "=" )
1063 | if subparts.Ubound = 1 then
1064 | pairs.Value( subparts( 0 ).Trim ) = subparts( 1 ).Trim
1065 | end if
1066 | next
1067 |
1068 | if pairs.HasKey( "charset" ) then
1069 | try
1070 | encoding = Xojo.Core.TextEncoding.FromIANAName( pairs.Value( "charset" ) )
1071 | catch err as RuntimeException
1072 | if err isa EndException or err isa ThreadEndException then
1073 | raise err
1074 | end if
1075 | end try
1076 | end if
1077 |
1078 | end if
1079 | end if
1080 |
1081 | dim textValue as text = encoding.ConvertDataToText( payload )
1082 | //
1083 | // If that crashes, the caller will handle it
1084 | //
1085 |
1086 | //
1087 | // Try to figure it out
1088 | //
1089 |
1090 | //
1091 | // JSON?
1092 | //
1093 | dim json as Xojo.Core.Dictionary
1094 | if subtype <> "xml" then
1095 | //
1096 | // We are going to try anything since the header could be wrong
1097 | //
1098 | try
1099 | json = Xojo.Data.ParseJSON( textValue )
1100 | subtype = "json"
1101 | result = json
1102 | catch err as RuntimeException
1103 | if err isa EndException or err isa ThreadEndException then
1104 | raise err
1105 | end if
1106 | end try
1107 | end if
1108 |
1109 | #if not TargetiOS then
1110 | //
1111 | // XML?
1112 | //
1113 | dim xml as XMLDocument
1114 | if subtype = "" or subtype = "xml" then
1115 | try
1116 | xml = new XmlDocument( textValue )
1117 | result = xml
1118 | subtype = "xml"
1119 | catch err as XmlException
1120 | //
1121 | // Do nothing
1122 | //
1123 | end try
1124 | end if
1125 | #endif
1126 |
1127 | if result = nil then
1128 | result = textValue
1129 | elseif json isa Xojo.Core.Dictionary then
1130 | //
1131 | // It's JSON, so let's try to parse it into the return
1132 | // properties
1133 | //
1134 | ProcessJSONPayload( json )
1135 | end if
1136 |
1137 | return result
1138 |
1139 | End Function
1140 | #tag EndMethod
1141 |
1142 | #tag Method, Flags = &h21
1143 | Private Shared Function PublicPropertiesToDictionary(ti As Xojo.Introspection.TypeInfo) As Xojo.Core.Dictionary
1144 | dim dict as new Xojo.Core.Dictionary
1145 |
1146 | dim props() as Xojo.Introspection.PropertyInfo = ti.Properties
1147 | for each prop as Xojo.Introspection.PropertyInfo in props
1148 | if prop.CanRead and prop.IsPublic and not prop.IsShared then
1149 | dict.Value( prop.Name ) = prop
1150 | end if
1151 | next
1152 |
1153 | return dict
1154 | End Function
1155 | #tag EndMethod
1156 |
1157 | #tag Method, Flags = &h0
1158 | Shared Function RESTTypeToHTTPAction(type As RESTTypes) As Text
1159 | select case type
1160 | case RESTTypes.Read, RESTTypes.GET
1161 | return kActionGet
1162 |
1163 | case RESTTypes.Create, RESTTypes.Authenticate, RESTTypes.POST
1164 | return kActionPost
1165 |
1166 | case RESTTypes.DELETE
1167 | return kActionDelete
1168 |
1169 | case RESTTypes.UpdateReplace, RESTTypes.PUT
1170 | return kActionPut
1171 |
1172 | case RESTTypes.UpdateModify, RESTTypes.PATCH
1173 | return kActionPatch
1174 |
1175 | case RESTTypes.OPTIONS
1176 | return kActionOptions
1177 |
1178 | case else
1179 | return kActionUnknown
1180 |
1181 | end select
1182 | End Function
1183 | #tag EndMethod
1184 |
1185 | #tag Method, Flags = &h0
1186 | Sub Send(surrogate As RESTMessageSurrogate_MTC = Nil)
1187 | RequestStartedMicroseconds = microseconds
1188 | ReceiveFinishedMicroseconds = -1.0
1189 |
1190 | dim action as text = HTTPAction
1191 | if action = kActionUnknown then
1192 | raise new M_REST.RESTException( "REST type was not specified" )
1193 | end if
1194 |
1195 | CreateMeta // Just in case
1196 | dim meta as M_REST.ClassMeta = MyMeta
1197 |
1198 | dim url as text = RaiseEvent GetURLPattern
1199 | url = url.Trim
1200 |
1201 | //
1202 | // Parse the URL
1203 | //
1204 | dim urlPropNames() as text
1205 | dim payloadProps() as Xojo.Introspection.PropertyInfo
1206 |
1207 | for each entry as Xojo.Core.DictionaryEntry in meta.SendPropertiesDict
1208 | dim prop as Xojo.Introspection.PropertyInfo = entry.Value
1209 | dim propName as text = prop.Name
1210 |
1211 | dim marker as text = ":" + prop.Name
1212 | if url.IndexOf( marker ) = -1 then
1213 | payloadProps.Append prop
1214 | else
1215 |
1216 | urlPropNames.Append propName
1217 | dim value as auto = prop.Value( self )
1218 |
1219 | //
1220 | // Get the text version of the value
1221 | //
1222 | dim tiValue as Xojo.Introspection.TypeInfo = Xojo.Introspection.GetType( value )
1223 | dim textValue as text
1224 |
1225 | select case tiValue.Name
1226 | case "Text"
1227 | //
1228 | // Already good
1229 | //
1230 | textValue = value
1231 |
1232 | case "Integer", "Int8", "Int16", "Int32", "Int64"
1233 | dim i as Int64 = value
1234 | textValue = i.ToText
1235 |
1236 | case "UInt8", "UInt16", "UInt32", "UInt64", "Byte"
1237 | dim i as UInt64 = value
1238 | textValue = i.ToText
1239 |
1240 | case "Double", "Single", "Currency"
1241 | dim d as double = value
1242 | textValue = d.ToText
1243 |
1244 | case "String"
1245 | #if not TargetiOS then
1246 | dim s as string = value
1247 | textValue = s.ToText
1248 | #endif
1249 |
1250 | case "Boolean"
1251 | const kTrueValue as text = "true"
1252 | const kFalseValue as text = "false"
1253 |
1254 | dim b as boolean = value
1255 | textValue = if( b, kTrueValue, kFalseValue )
1256 |
1257 | case else
1258 | if value isa M_REST.TextProvider then
1259 | textValue = M_REST.TextProvider( value ).ConvertToText
1260 | else
1261 | raise new M_REST.RESTException( "The property " + propName + " cannot be converted to Text" )
1262 | end if
1263 | end select
1264 |
1265 | url = url.ReplaceAll( marker, textValue )
1266 | end if
1267 | next
1268 |
1269 | dim payload as Xojo.Core.MemoryBlock
1270 | if action <> kActionGet and payloadProps.Ubound <> -1 and MessageOptions.SendWithPayloadIfAvailable then
1271 | payload = CreateOutgoingPayload( payloadProps )
1272 | end if
1273 |
1274 | dim mimeType as text = "application/json"
1275 | if RaiseEvent CancelSend( url, action, payload, mimeType ) then
1276 | return
1277 | end if
1278 |
1279 | if payload isa object then
1280 | if mimeType = "" then
1281 | Raise new M_REST.RESTException( "No MIME type specified" )
1282 | end if
1283 |
1284 | SetRequestContent payload, mimeType
1285 | end if
1286 |
1287 | MessageSurrogate = surrogate
1288 | Send action, url
1289 |
1290 | if surrogate isa object then
1291 | PrivateSurrogate(surrogate).RaiseSent self
1292 | end if
1293 |
1294 | End Sub
1295 | #tag EndMethod
1296 |
1297 | #tag Method, Flags = &h1
1298 | Protected Sub Send(method as Text, url as Text)
1299 | //
1300 | // Disable external access to this
1301 | //
1302 |
1303 | PrepareToSend
1304 | super.Send( method, url )
1305 |
1306 | End Sub
1307 | #tag EndMethod
1308 |
1309 | #tag Method, Flags = &h1
1310 | Protected Sub Send(method as Text, url as Text, file as Xojo.IO.FolderItem)
1311 | //
1312 | // Disable external access to this
1313 | //
1314 |
1315 | PrepareToSend
1316 | super.Send( method, url, file )
1317 | End Sub
1318 | #tag EndMethod
1319 |
1320 | #tag Method, Flags = &h1
1321 | Protected Function Serialize(value As Auto) As Auto
1322 | dim ti as Xojo.Introspection.TypeInfo = Xojo.Introspection.GetType( value )
1323 | if ti is nil then
1324 | return nil
1325 | end if
1326 |
1327 | dim type as text = ti.Name
1328 | if type.Length > 2 and type.EndsWith( "()" ) then
1329 | return SerializeArray( value, ti )
1330 |
1331 | elseif type = "String" then
1332 | #if not TargetiOS then
1333 | dim s as string = value
1334 | dim t as text = s.ToText
1335 | return t
1336 | #endif
1337 |
1338 | elseif type = "Currency" then
1339 | dim c as currency = value
1340 | dim d as double = c
1341 | return d
1342 |
1343 | elseif IsIntrinsicType( type ) then
1344 | return value
1345 |
1346 | else
1347 | return SerializeObject( value, ti )
1348 |
1349 | end if
1350 |
1351 | End Function
1352 | #tag EndMethod
1353 |
1354 | #tag Method, Flags = &h21
1355 | Private Function SerializeArray(value As Auto, ti As Xojo.Introspection.TypeInfo) As Auto
1356 | if ti.Name = "String()" then
1357 | //
1358 | // Convert the string to text to make sure JSON can handle it
1359 | //
1360 | #if not TargetiOS then
1361 | dim arr() as string = value
1362 | dim result() as text
1363 | redim result( arr.Ubound )
1364 | for i as integer = 0 to arr.Ubound
1365 | result( i ) = arr( i ).ToText
1366 | next i
1367 | return result
1368 | #endif
1369 |
1370 | elseif ti.Name = "Currency()" then
1371 | //
1372 | // JSON can't handle currency so convert to a double
1373 | //
1374 | dim arr() as currency = value
1375 | dim result() as double
1376 | redim result( arr.Ubound )
1377 | for i as integer = 0 to arr.Ubound
1378 | result( i ) = arr( i )
1379 | next
1380 | return result
1381 |
1382 | elseif IsIntrinsicType( ti.Name ) then
1383 | //
1384 | // It's another basic type so just return it
1385 | //
1386 | return value
1387 |
1388 | else // It's some object array
1389 | dim arr() as object = value
1390 | dim result() as auto
1391 | redim result( arr.Ubound )
1392 | for i as integer = 0 to arr.Ubound
1393 | result( i ) = Serialize( arr( i ) )
1394 | next
1395 | return result
1396 |
1397 | end if
1398 |
1399 | End Function
1400 | #tag EndMethod
1401 |
1402 | #tag Method, Flags = &h21
1403 | Private Function SerializeDate(d As Xojo.Core.Date) As Text
1404 | //
1405 | // Returns ISO 8601 format
1406 | //
1407 | // https://en.wikipedia.org/wiki/ISO_8601
1408 | //
1409 |
1410 |
1411 | dim result as text
1412 |
1413 | if MessageOptions.AdjustDatesForTimeZone then
1414 | dim tz as Xojo.Core.TimeZone = d.TimeZone
1415 | dim interval as new Xojo.Core.DateInterval( 0, 0, 0, 0, 0, tz.SecondsFromGMT )
1416 | d = d - interval
1417 | end if
1418 |
1419 | dim locale as Xojo.Core.Locale = Xojo.Core.Locale.Current
1420 |
1421 | result = d.Year.ToText( locale, "0000" ) + "-" + d.Month.ToText( locale, "00" ) + "-" + d.Day.ToText( locale, "00" )
1422 | result = result + "T" + d.Hour.ToText( locale, "00" ) + ":" + d.Minute.ToText( locale, "00" ) + ":" + _
1423 | d.Second.ToText( locale, "00" ) + "Z"
1424 |
1425 | return result
1426 |
1427 | End Function
1428 | #tag EndMethod
1429 |
1430 | #tag Method, Flags = &h21
1431 | Private Function SerializeDictionary(dict As Xojo.Core.Dictionary) As Xojo.Core.Dictionary
1432 | dim result as new Xojo.Core.Dictionary
1433 |
1434 | for each entry as Xojo.Core.DictionaryEntry in dict
1435 | result.Value( entry.Key ) = Serialize( entry.Value )
1436 | next
1437 |
1438 | return result
1439 |
1440 | End Function
1441 | #tag EndMethod
1442 |
1443 | #tag Method, Flags = &h21
1444 | Private Function SerializeObject(o As Object, ti As Xojo.Introspection.TypeInfo) As Auto
1445 | //
1446 | // See if the subclass wants to tackle this
1447 | //
1448 | if true then // Scope
1449 | dim autoResult as Auto = RaiseEvent ObjectToJSON( o, ti )
1450 | if autoResult <> nil then
1451 | return autoResult // *** EARLY EXIT
1452 | end if
1453 | end if
1454 |
1455 |
1456 | #if not TargetiOS then
1457 | if o isa Dictionary then
1458 | //
1459 | // We are going to do this here
1460 | //
1461 | dim result as new Xojo.Core.Dictionary
1462 |
1463 | dim d as Dictionary = Dictionary( o )
1464 | dim keys() as variant = d.Keys
1465 | dim values() as variant = d.Values
1466 | for i as integer = 0 to keys.Ubound
1467 | result.Value( keys( i ) ) = Serialize( values( i ) )
1468 | next
1469 | return result // *** EARLY EXIT
1470 | end if
1471 |
1472 | if o isa Date then
1473 | //
1474 | // Convert it to a new Date
1475 | //
1476 | dim d as Date = Date( o )
1477 | dim tz as new Xojo.Core.TimeZone( d.GMTOffset * 60 * 60 )
1478 | o = new Xojo.Core.Date( d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second, 0, tz )
1479 | end if
1480 | #endif
1481 |
1482 | if o isa Xojo.Core.Date then
1483 | return SerializeDate( Xojo.Core.Date( o ) ) // *** EARLY EXIT
1484 | else
1485 | dim result as new Xojo.Core.Dictionary
1486 |
1487 | for each prop as Xojo.Introspection.PropertyInfo in ti.Properties
1488 | if prop.IsPublic and prop.CanRead and not prop.IsShared then
1489 | result.Value( prop.Name ) = Serialize( prop.Value( o ) )
1490 | end if
1491 | next
1492 |
1493 | return result
1494 | end if
1495 |
1496 | End Function
1497 | #tag EndMethod
1498 |
1499 | #tag Method, Flags = &h21
1500 | Private Sub TimeoutTimer_Action(sender As Xojo.Core.Timer)
1501 | dim surrogate as M_REST.PrivateSurrogate = MessageSurrogate
1502 |
1503 | if IsConnected then
1504 | if RaiseEvent ContinueWaiting or (surrogate isa object and surrogate.RaiseContinueWaiting( self ) ) then
1505 | //
1506 | // One of these wanted to continue waiting
1507 | //
1508 | else
1509 | self.Disconnect
1510 | end if
1511 | end if
1512 |
1513 | sender.Mode = Xojo.Core.Timer.Modes.Off
1514 | if IsConnected then
1515 | sender.Mode = Xojo.Core.Timer.Modes.Multiple
1516 | end if
1517 |
1518 | End Sub
1519 | #tag EndMethod
1520 |
1521 |
1522 | #tag Hook, Flags = &h0
1523 | Event AuthenticationRequired(realm As Text, ByRef username As Text, ByRef password As Text) As Boolean
1524 | #tag EndHook
1525 |
1526 | #tag Hook, Flags = &h0, Description = 4C617374206368616E636520746F2063616E63656C20612073656E64206F72206D6F64696679207468652076616C7565732069742077696C6C207573652E
1527 | Event CancelSend(ByRef url As Text, ByRef httpAction As Text, ByRef payload As Xojo.Core.MemoryBlock, ByRef payloadMIMEType As Text) As Boolean
1528 | #tag EndHook
1529 |
1530 | #tag Hook, Flags = &h0, Description = 546865206D6573736167652068617320657863656564207468652074696D652073657420696E204F7074696F6E732E54696D656F75745365636F6E64732E2052657475726E205472756520746F20616C6C6F7720746865206D65737361676520746F206B6565702077616974696E672E
1531 | Event ContinueWaiting() As Boolean
1532 | #tag EndHook
1533 |
1534 | #tag Hook, Flags = &h0, Description = 54686520736F636B65742068617320646973636F6E6E65637465642E
1535 | Event Disconnected()
1536 | #tag EndHook
1537 |
1538 | #tag Hook, Flags = &h0, Description = 416E206572726F7220686173206F636375727265642E
1539 | Event Error(msg As Text)
1540 | #tag EndHook
1541 |
1542 | #tag Hook, Flags = &h0, Description = 4578636C75646520612070726F70657274792066726F6D20746865206F7574676F696E67207061796C6F6164207468617420776F756C64206F746865727769736520626520696E636C756465642C206F72206368616E6765207468652070726F7065727479206E616D6520616E642F6F722076616C756520746861742077696C6C20626520757365642E
1543 | Event ExcludeFromOutgoingPayload(prop As Xojo.Introspection.PropertyInfo, ByRef propName As Text, ByRef propValue As Auto) As Boolean
1544 | #tag EndHook
1545 |
1546 | #tag Hook, Flags = &h0, Description = 5468652052455354207479706520746F2075736520666F72207468697320636F6E6E656374696F6E2E204966206E6F7420696D706C656D656E7465642C2044656661756C7452455354547970652077696C6C206265207573656420696E73746561642E
1547 | Event GetRESTType() As RESTTypes
1548 | #tag EndHook
1549 |
1550 | #tag Hook, Flags = &h0, Description = 5468652055524C207061747465726E20746F2075736520666F722074686520636F6E6E656374696F6E2E2043616E20696E636C7564652070726F7065727479206E616D657320746861742077696C6C20626520737562737469747574656420666F722076616C75652C20652E672E2C0A0A687474703A2F2F7777772E6578616D706C652E636F6D2F6765742F3A69643F6E616D653D3A6E616D650A0A3A696420616E64203A6E616D652077696C6C206265207265706C616365642062792070726F70657274696573206F66207468652073616D65206E616D652E
1551 | Event GetURLPattern() As Text
1552 | #tag EndHook
1553 |
1554 | #tag Hook, Flags = &h0
1555 | Event HeadersReceived(url As Text, httpStatus As Integer)
1556 | #tag EndHook
1557 |
1558 | #tag Hook, Flags = &h0, Description = 4D616E75616C6C792073746F72652074686520696E636F6D696E67207061796C6F61642076616C756520617320646573697265642E2052657475726E205472756520746F2070726576656E7420667572746865722070726F63657373696E67206F6E20746861742076616C75652E
1559 | Event IncomingPayloadValueToProperty(value As Auto, prop As Xojo.Introspection.PropertyInfo, hostObject As Object) As Boolean
1560 | #tag EndHook
1561 |
1562 | #tag Hook, Flags = &h0, Description = 4D616E75616C6C7920636F6E7665727420616E206F626A65637420746F204A534F4E20666F7220696E636C7573696F6E20696E20746865206F7574676F696E67207061796C6F61642E
1563 | Event ObjectToJSON(o As Object, typeInfo As Xojo.Introspection.TypeInfo) As Auto
1564 | #tag EndHook
1565 |
1566 | #tag Hook, Flags = &h0
1567 | Event ReceiveProgress(bytesReceived As Int64, totalBytes As Int64, newData As Xojo.Core.MemoryBlock)
1568 | #tag EndHook
1569 |
1570 | #tag Hook, Flags = &h0, Description = 546865205245535466756C20736572766572206861732072657475726E6564206120726573706F6E73652E
1571 | Event ResponseReceived(url As Text, httpStatus As Integer, payload As Auto)
1572 | #tag EndHook
1573 |
1574 | #tag Hook, Flags = &h0
1575 | Event SendProgress(bytesSent As Int64, bytesLeft As Int64)
1576 | #tag EndHook
1577 |
1578 | #tag Hook, Flags = &h0, Description = 5365742075702070726F70657274696573206F722074616B65206F7468657220616374696F6E732061667465722074686520696E7374616E636520697320666972737420636F6E73747275637465642E
1579 | Event Setup()
1580 | #tag EndHook
1581 |
1582 | #tag Hook, Flags = &h0, Description = 52657475726E205472756520746F2070726576656E74206175746F6D617469632070726F63657373696E67206F662074686520696E636F6D696E67207061796C6F61642C206F72206368616E676520746865207061796C6F6164206265666F7265206175746F6D617469632070726F63657373696E672E
1583 | Event SkipIncomingPayloadProcessing(url As Text, httpStatus As Integer, ByRef payload As Auto) As Boolean
1584 | #tag EndHook
1585 |
1586 |
1587 | #tag Property, Flags = &h21
1588 | Private Shared ClassMetaDict As Xojo.Core.Dictionary
1589 | #tag EndProperty
1590 |
1591 | #tag Property, Flags = &h21
1592 | Private ClassName As Text
1593 | #tag EndProperty
1594 |
1595 | #tag Property, Flags = &h0
1596 | DefaultRESTType As RESTTypes = RESTTypes.Unknown
1597 | #tag EndProperty
1598 |
1599 | #tag Property, Flags = &h21
1600 | Private FlagGetRESTType As Boolean
1601 | #tag EndProperty
1602 |
1603 | #tag ComputedProperty, Flags = &h1
1604 | #tag Getter
1605 | Get
1606 | return RESTTypeToHTTPAction( RESTType )
1607 | End Get
1608 | #tag EndGetter
1609 | Protected HTTPAction As Text
1610 | #tag EndComputedProperty
1611 |
1612 | #tag ComputedProperty, Flags = &h0
1613 | #tag Getter
1614 | Get
1615 | return mIsConnected
1616 | End Get
1617 | #tag EndGetter
1618 | IsConnected As Boolean
1619 | #tag EndComputedProperty
1620 |
1621 | #tag ComputedProperty, Flags = &h0
1622 | #tag Getter
1623 | Get
1624 | if mMessageOptions is nil then
1625 | MessageOptions = new M_REST.Options
1626 | end if
1627 |
1628 | return mMessageOptions
1629 | End Get
1630 | #tag EndGetter
1631 | #tag Setter
1632 | Set
1633 | if value = mMessageOptions then
1634 | //
1635 | // Nothing to do
1636 | //
1637 | return
1638 | end if
1639 |
1640 | if mMessageOptions isa Object then
1641 | //
1642 | // Clear the parent
1643 | //
1644 | PrivateOptions( mMessageOptions ).SetParentMessage nil
1645 | end if
1646 |
1647 | mMessageOptions = value
1648 | if mMessageOptions isa Object then
1649 | PrivateOptions( mMessageOptions ).SetParentMessage self
1650 | end if
1651 |
1652 | End Set
1653 | #tag EndSetter
1654 | MessageOptions As M_REST.Options
1655 | #tag EndComputedProperty
1656 |
1657 | #tag ComputedProperty, Flags = &h0
1658 | #tag Getter
1659 | Get
1660 | static nextSN as Int64
1661 | static accessFlag as new Semaphore( 1 )
1662 |
1663 | if mMessageSerialNumber <= 0 then
1664 | accessFlag.Signal
1665 |
1666 | const kOne as Int64 = 1
1667 | nextSN = nextSN + kOne
1668 | mMessageSerialNumber = nextSN
1669 |
1670 | accessFlag.Release
1671 | end if
1672 |
1673 | return mMessageSerialNumber
1674 |
1675 | End Get
1676 | #tag EndGetter
1677 | MessageSerialNumber As Int64
1678 | #tag EndComputedProperty
1679 |
1680 | #tag ComputedProperty, Flags = &h21
1681 | #tag Getter
1682 | Get
1683 | if mMessageSurrogateWeakRef is nil then
1684 | return nil
1685 | else
1686 | return PrivateSurrogate( mMessageSurrogateWeakRef.Value )
1687 | end if
1688 |
1689 | End Get
1690 | #tag EndGetter
1691 | #tag Setter
1692 | Set
1693 | if value is nil then
1694 | mMessageSurrogateWeakRef = nil
1695 | else
1696 | mMessageSurrogateWeakRef = Xojo.Core.WeakRef.Create( value )
1697 | value.AppendMessage self
1698 | end if
1699 |
1700 | End Set
1701 | #tag EndSetter
1702 | Private MessageSurrogate As PrivateSurrogate
1703 | #tag EndComputedProperty
1704 |
1705 | #tag Property, Flags = &h0
1706 | MessageTag As Auto
1707 | #tag EndProperty
1708 |
1709 | #tag Property, Flags = &h21
1710 | Attributes( hidden ) Private mIsConnected As Boolean
1711 | #tag EndProperty
1712 |
1713 | #tag Property, Flags = &h21
1714 | Attributes( hidden ) Private mMessageOptions As M_REST.Options
1715 | #tag EndProperty
1716 |
1717 | #tag Property, Flags = &h21
1718 | Attributes( hidden ) Private mMessageSerialNumber As Int64
1719 | #tag EndProperty
1720 |
1721 | #tag Property, Flags = &h21
1722 | Private mMessageSurrogateWeakRef As Xojo.Core.WeakRef
1723 | #tag EndProperty
1724 |
1725 | #tag ComputedProperty, Flags = &h21
1726 | #tag Getter
1727 | Get
1728 | if ClassMetaDict is nil then
1729 | return nil
1730 | end if
1731 |
1732 | if ClassName = "" then
1733 | return nil
1734 | end if
1735 |
1736 | return ClassMetaDict.Value( ClassName )
1737 | End Get
1738 | #tag EndGetter
1739 | Private MyMeta As M_REST.ClassMeta
1740 | #tag EndComputedProperty
1741 |
1742 | #tag Property, Flags = &h21
1743 | Private ReceiveFinishedMicroseconds As Double
1744 | #tag EndProperty
1745 |
1746 | #tag Property, Flags = &h21
1747 | Private RequestSentMicroseconds As Double = -1.0
1748 | #tag EndProperty
1749 |
1750 | #tag Property, Flags = &h21
1751 | Private RequestStartedMicroseconds As Double = -1.0
1752 | #tag EndProperty
1753 |
1754 | #tag Property, Flags = &h21
1755 | Private ResponseReceivedMicroseconds As Double = -1.0
1756 | #tag EndProperty
1757 |
1758 | #tag ComputedProperty, Flags = &h0
1759 | #tag Getter
1760 | Get
1761 | if FlagGetRESTType then
1762 | return DefaultRESTType
1763 | end if
1764 |
1765 | FlagGetRESTType = true
1766 | dim type as RESTTypes = RaiseEvent GetRESTType
1767 | if type = RESTTypes.Unknown then
1768 | type = DefaultRESTType
1769 | end if
1770 | FlagGetRESTType = false
1771 |
1772 | return type
1773 | End Get
1774 | #tag EndGetter
1775 | RESTType As RESTTypes
1776 | #tag EndComputedProperty
1777 |
1778 | #tag ComputedProperty, Flags = &h0
1779 | #tag Getter
1780 | Get
1781 | dim roundTrip as double
1782 |
1783 | if ResponseReceivedMicroseconds < 0.0 or RequestSentMicroseconds < 0.0 then
1784 | roundTrip = -1.0
1785 | else
1786 | roundTrip = ( ResponseReceivedMicroseconds - RequestSentMicroseconds ) / 1000.0
1787 | end if
1788 |
1789 | if roundTrip < 0.0 then
1790 | roundTrip = -1.0
1791 | end if
1792 |
1793 | return roundTrip
1794 | End Get
1795 | #tag EndGetter
1796 | RoundTripMs As Double
1797 | #tag EndComputedProperty
1798 |
1799 | #tag ComputedProperty, Flags = &h0
1800 | #tag Getter
1801 | Get
1802 | dim roundTrip as double
1803 |
1804 | if ReceiveFinishedMicroseconds < 0.0 or RequestStartedMicroseconds < 0.0 then
1805 | roundTrip = -1.0
1806 | else
1807 | roundTrip = ( ReceiveFinishedMicroseconds - RequestStartedMicroseconds ) / 1000.0
1808 | end if
1809 |
1810 | if roundTrip < 0.0 then
1811 | roundTrip = -1.0
1812 | end if
1813 |
1814 | return roundTrip
1815 | End Get
1816 | #tag EndGetter
1817 | RoundTripWithProcessingMs As Double
1818 | #tag EndComputedProperty
1819 |
1820 | #tag Property, Flags = &h21
1821 | Private TimeoutTimer As Xojo.Core.Timer
1822 | #tag EndProperty
1823 |
1824 |
1825 | #tag Constant, Name = kActionDelete, Type = Text, Dynamic = False, Default = \"DELETE", Scope = Protected
1826 | #tag EndConstant
1827 |
1828 | #tag Constant, Name = kActionGet, Type = Text, Dynamic = False, Default = \"GET", Scope = Protected
1829 | #tag EndConstant
1830 |
1831 | #tag Constant, Name = kActionOptions, Type = Text, Dynamic = False, Default = \"OPTIONS", Scope = Protected
1832 | #tag EndConstant
1833 |
1834 | #tag Constant, Name = kActionPatch, Type = Text, Dynamic = False, Default = \"PATCH", Scope = Protected
1835 | #tag EndConstant
1836 |
1837 | #tag Constant, Name = kActionPost, Type = Text, Dynamic = False, Default = \"POST", Scope = Protected
1838 | #tag EndConstant
1839 |
1840 | #tag Constant, Name = kActionPut, Type = Text, Dynamic = False, Default = \"PUT", Scope = Protected
1841 | #tag EndConstant
1842 |
1843 | #tag Constant, Name = kActionUnknown, Type = Text, Dynamic = False, Default = \"Unknown", Scope = Protected
1844 | #tag EndConstant
1845 |
1846 | #tag Constant, Name = kContentType, Type = Text, Dynamic = False, Default = \"application/json", Scope = Private
1847 | #tag EndConstant
1848 |
1849 | #tag Constant, Name = kVersion, Type = Text, Dynamic = False, Default = \"1.2", Scope = Public
1850 | #tag EndConstant
1851 |
1852 |
1853 | #tag Enum, Name = RESTTypes, Type = Integer, Flags = &h0
1854 | Unknown
1855 | Create
1856 | Read
1857 | UpdateReplace
1858 | UpdateModify
1859 | Authenticate
1860 | DELETE
1861 | GET
1862 | HEAD
1863 | OPTIONS
1864 | PATCH
1865 | POST
1866 | PUT
1867 | #tag EndEnum
1868 |
1869 |
1870 | #tag ViewBehavior
1871 | #tag ViewProperty
1872 | Name="DefaultRESTType"
1873 | Visible=true
1874 | Group="Behavior"
1875 | InitialValue="RESTTypes.Unknown"
1876 | Type="RESTTypes"
1877 | EditorType="Enum"
1878 | #tag EnumValues
1879 | "0 - Unknown"
1880 | "1 - Create"
1881 | "2 - Read"
1882 | "3 - UpdateReplace"
1883 | "4 - UpdateModify"
1884 | "5 - Authenticate"
1885 | "6 - DELETE"
1886 | "7 - GET"
1887 | "8 - HEAD"
1888 | "9 - OPTIONS"
1889 | "10 - PATCH"
1890 | "11 - POST"
1891 | "12 - PUT"
1892 | #tag EndEnumValues
1893 | #tag EndViewProperty
1894 | #tag ViewProperty
1895 | Name="Index"
1896 | Visible=true
1897 | Group="ID"
1898 | InitialValue="-2147483648"
1899 | Type="Integer"
1900 | #tag EndViewProperty
1901 | #tag ViewProperty
1902 | Name="IsConnected"
1903 | Group="Behavior"
1904 | Type="Boolean"
1905 | #tag EndViewProperty
1906 | #tag ViewProperty
1907 | Name="Left"
1908 | Visible=true
1909 | Group="Position"
1910 | InitialValue="0"
1911 | Type="Integer"
1912 | #tag EndViewProperty
1913 | #tag ViewProperty
1914 | Name="MessageSerialNumber"
1915 | Group="Behavior"
1916 | Type="Int64"
1917 | #tag EndViewProperty
1918 | #tag ViewProperty
1919 | Name="Name"
1920 | Visible=true
1921 | Group="ID"
1922 | Type="String"
1923 | #tag EndViewProperty
1924 | #tag ViewProperty
1925 | Name="RESTType"
1926 | Group="Behavior"
1927 | Type="RESTTypes"
1928 | EditorType="Enum"
1929 | #tag EnumValues
1930 | "0 - Unknown"
1931 | "1 - Create"
1932 | "2 - Read"
1933 | "3 - UpdateReplace"
1934 | "4 - UpdateModify"
1935 | "5 - Authenticate"
1936 | "6 - DELETE"
1937 | "7 - GET"
1938 | "8 - HEAD"
1939 | "9 - OPTIONS"
1940 | "10 - PATCH"
1941 | "11 - POST"
1942 | "12 - PUT"
1943 | #tag EndEnumValues
1944 | #tag EndViewProperty
1945 | #tag ViewProperty
1946 | Name="RoundTripMs"
1947 | Group="Behavior"
1948 | Type="Double"
1949 | #tag EndViewProperty
1950 | #tag ViewProperty
1951 | Name="RoundTripWithProcessingMs"
1952 | Group="Behavior"
1953 | Type="Double"
1954 | #tag EndViewProperty
1955 | #tag ViewProperty
1956 | Name="Super"
1957 | Visible=true
1958 | Group="ID"
1959 | Type="String"
1960 | #tag EndViewProperty
1961 | #tag ViewProperty
1962 | Name="Top"
1963 | Visible=true
1964 | Group="Position"
1965 | InitialValue="0"
1966 | Type="Integer"
1967 | #tag EndViewProperty
1968 | #tag ViewProperty
1969 | Name="ValidateCertificates"
1970 | Visible=true
1971 | Group="Behavior"
1972 | Type="Boolean"
1973 | #tag EndViewProperty
1974 | #tag EndViewBehavior
1975 | End Class
1976 | #tag EndClass
1977 |
--------------------------------------------------------------------------------
/REST Resources/M_REST/TextProvider.xojo_code:
--------------------------------------------------------------------------------
1 | #tag Interface
2 | Protected Interface TextProvider
3 | #tag Method, Flags = &h0
4 | Function ConvertToText() As Text
5 |
6 | End Function
7 | #tag EndMethod
8 |
9 |
10 | #tag ViewBehavior
11 | #tag ViewProperty
12 | Name="Index"
13 | Visible=true
14 | Group="ID"
15 | InitialValue="-2147483648"
16 | Type="Integer"
17 | #tag EndViewProperty
18 | #tag ViewProperty
19 | Name="Left"
20 | Visible=true
21 | Group="Position"
22 | InitialValue="0"
23 | Type="Integer"
24 | #tag EndViewProperty
25 | #tag ViewProperty
26 | Name="Name"
27 | Visible=true
28 | Group="ID"
29 | Type="String"
30 | #tag EndViewProperty
31 | #tag ViewProperty
32 | Name="Super"
33 | Visible=true
34 | Group="ID"
35 | Type="String"
36 | #tag EndViewProperty
37 | #tag ViewProperty
38 | Name="Top"
39 | Visible=true
40 | Group="Position"
41 | InitialValue="0"
42 | Type="Integer"
43 | #tag EndViewProperty
44 | #tag EndViewBehavior
45 | End Interface
46 | #tag EndInterface
47 |
--------------------------------------------------------------------------------