sfdcvp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +15 -0
  2. data/Changelog.txt +1004 -0
  3. data/README.md +201 -0
  4. data/TODO +17 -0
  5. data/lib/ews/calendar_accessors.rb +34 -0
  6. data/lib/ews/connection.rb +126 -0
  7. data/lib/ews/connection_helper.rb +35 -0
  8. data/lib/ews/convert_accessors.rb +56 -0
  9. data/lib/ews/errors.rb +56 -0
  10. data/lib/ews/ews_client.rb +101 -0
  11. data/lib/ews/exceptions/exceptions.rb +61 -0
  12. data/lib/ews/folder_accessors.rb +264 -0
  13. data/lib/ews/impersonation.rb +30 -0
  14. data/lib/ews/item_accessors.rb +231 -0
  15. data/lib/ews/mailbox_accessors.rb +92 -0
  16. data/lib/ews/message_accessors.rb +93 -0
  17. data/lib/ews/push_subscription_accessors.rb +33 -0
  18. data/lib/ews/room_accessors.rb +48 -0
  19. data/lib/ews/roomlist_accessors.rb +47 -0
  20. data/lib/ews/soap.rb +64 -0
  21. data/lib/ews/soap/builders/ews_builder.rb +1361 -0
  22. data/lib/ews/soap/ews_response.rb +84 -0
  23. data/lib/ews/soap/ews_soap_availability_response.rb +58 -0
  24. data/lib/ews/soap/ews_soap_free_busy_response.rb +119 -0
  25. data/lib/ews/soap/ews_soap_response.rb +103 -0
  26. data/lib/ews/soap/ews_soap_room_response.rb +53 -0
  27. data/lib/ews/soap/ews_soap_roomlist_response.rb +54 -0
  28. data/lib/ews/soap/exchange_availability.rb +61 -0
  29. data/lib/ews/soap/exchange_data_services.rb +780 -0
  30. data/lib/ews/soap/exchange_notification.rb +146 -0
  31. data/lib/ews/soap/exchange_synchronization.rb +93 -0
  32. data/lib/ews/soap/exchange_time_zones.rb +56 -0
  33. data/lib/ews/soap/exchange_user_configuration.rb +33 -0
  34. data/lib/ews/soap/exchange_web_service.rb +264 -0
  35. data/lib/ews/soap/parsers/ews_parser.rb +43 -0
  36. data/lib/ews/soap/parsers/ews_sax_document.rb +70 -0
  37. data/lib/ews/soap/response_message.rb +80 -0
  38. data/lib/ews/soap/responses/create_attachment_response_message.rb +47 -0
  39. data/lib/ews/soap/responses/create_item_response_message.rb +25 -0
  40. data/lib/ews/soap/responses/find_item_response_message.rb +80 -0
  41. data/lib/ews/soap/responses/get_events_response_message.rb +53 -0
  42. data/lib/ews/soap/responses/send_notification_response_message.rb +59 -0
  43. data/lib/ews/soap/responses/subscribe_response_message.rb +35 -0
  44. data/lib/ews/soap/responses/sync_folder_hierarchy_response_message.rb +36 -0
  45. data/lib/ews/soap/responses/sync_folder_items_response_message.rb +36 -0
  46. data/lib/ews/templates/calendar_item.rb +78 -0
  47. data/lib/ews/templates/forward_item.rb +24 -0
  48. data/lib/ews/templates/message.rb +73 -0
  49. data/lib/ews/templates/reply_to_item.rb +25 -0
  50. data/lib/ews/templates/task.rb +74 -0
  51. data/lib/ews/types.rb +194 -0
  52. data/lib/ews/types/attachment.rb +77 -0
  53. data/lib/ews/types/attendee.rb +27 -0
  54. data/lib/ews/types/calendar_folder.rb +50 -0
  55. data/lib/ews/types/calendar_item.rb +129 -0
  56. data/lib/ews/types/contact.rb +7 -0
  57. data/lib/ews/types/contacts_folder.rb +8 -0
  58. data/lib/ews/types/copied_event.rb +51 -0
  59. data/lib/ews/types/created_event.rb +24 -0
  60. data/lib/ews/types/deleted_event.rb +24 -0
  61. data/lib/ews/types/distribution_list.rb +7 -0
  62. data/lib/ews/types/event.rb +62 -0
  63. data/lib/ews/types/export_items_response_message.rb +52 -0
  64. data/lib/ews/types/file_attachment.rb +65 -0
  65. data/lib/ews/types/folder.rb +60 -0
  66. data/lib/ews/types/free_busy_changed_event.rb +24 -0
  67. data/lib/ews/types/generic_folder.rb +420 -0
  68. data/lib/ews/types/item.rb +442 -0
  69. data/lib/ews/types/item_attachment.rb +84 -0
  70. data/lib/ews/types/item_field_uri_map.rb +224 -0
  71. data/lib/ews/types/mailbox_user.rb +156 -0
  72. data/lib/ews/types/meeting_cancellation.rb +7 -0
  73. data/lib/ews/types/meeting_message.rb +7 -0
  74. data/lib/ews/types/meeting_request.rb +7 -0
  75. data/lib/ews/types/meeting_response.rb +7 -0
  76. data/lib/ews/types/message.rb +7 -0
  77. data/lib/ews/types/modified_event.rb +48 -0
  78. data/lib/ews/types/moved_event.rb +51 -0
  79. data/lib/ews/types/new_mail_event.rb +24 -0
  80. data/lib/ews/types/out_of_office.rb +147 -0
  81. data/lib/ews/types/search_folder.rb +8 -0
  82. data/lib/ews/types/status_event.rb +39 -0
  83. data/lib/ews/types/task.rb +37 -0
  84. data/lib/ews/types/tasks_folder.rb +27 -0
  85. data/lib/sfdcvp.rb +109 -0
  86. data/lib/viewpoint/logging.rb +27 -0
  87. data/lib/viewpoint/logging/config.rb +24 -0
  88. data/lib/viewpoint/string_utils.rb +76 -0
  89. metadata +190 -0
@@ -0,0 +1,35 @@
1
+ =begin
2
+ This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::EWS::SOAP
20
+ class SubscribeResponseMessage < ResponseMessage
21
+
22
+ def subscription
23
+ safe_hash_access message, [:elems]
24
+ end
25
+
26
+ def subscription_id
27
+ safe_hash_access subscription, [:subscription_id, :text]
28
+ end
29
+
30
+ def watermark
31
+ safe_hash_access subscription, [:watermark, :text]
32
+ end
33
+
34
+ end # SubscribeResponseMessage
35
+ end # Viewpoint::EWS::SOAP
@@ -0,0 +1,36 @@
1
+ =begin
2
+ This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::EWS::SOAP
20
+ class SyncFolderHierarchyResponseMessage < ResponseMessage
21
+
22
+ def sync_state
23
+ safe_hash_access message, [:elems, :sync_state, :text]
24
+ end
25
+
26
+ def includes_last_folder_in_range?
27
+ ans = safe_hash_access message, [:elems, :includes_last_folder_in_range, :text]
28
+ ans.downcase == 'true'
29
+ end
30
+
31
+ def changes
32
+ safe_hash_access(message, [:elems, :changes, :elems]) || []
33
+ end
34
+
35
+ end # SyncFolderHierarchyResponseMessage
36
+ end # Viewpoint::EWS::SOAP
@@ -0,0 +1,36 @@
1
+ =begin
2
+ This file is part of Viewpoint; the Ruby library for Microsoft Exchange Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::EWS::SOAP
20
+ class SyncFolderItemsResponseMessage < ResponseMessage
21
+
22
+ def sync_state
23
+ safe_hash_access message, [:elems, :sync_state, :text]
24
+ end
25
+
26
+ def includes_last_item_in_range?
27
+ ans = safe_hash_access message, [:elems, :includes_last_item_in_range, :text]
28
+ ans.downcase == 'true'
29
+ end
30
+
31
+ def changes
32
+ safe_hash_access(message, [:elems, :changes, :elems]) || []
33
+ end
34
+
35
+ end # SyncFolderItemsResponseMessage
36
+ end # Viewpoint::EWS::SOAP
@@ -0,0 +1,78 @@
1
+ module Viewpoint::EWS
2
+ module Template
3
+ # Template for creating CalendarItems
4
+ # @see http://msdn.microsoft.com/en-us/library/exchange/aa564765.aspx
5
+ class CalendarItem < OpenStruct
6
+
7
+ # Available parameters with the required ordering
8
+ PARAMETERS = %w{mime_content item_id parent_folder_id item_class subject sensitivity body attachments
9
+ date_time_received size categories in_reply_to is_submitted is_draft is_from_me is_resend is_unmodified
10
+ internet_message_headers date_time_sent date_time_created response_objects reminder_due_by reminder_is_set
11
+ reminder_minutes_before_start display_cc display_to has_attachments extended_property culture start end
12
+ original_start is_all_day_event legacy_free_busy_status location when is_meeting is_cancelled is_recurring
13
+ meeting_request_was_sent is_response_requested calendar_item_type my_response_type organizer
14
+ required_attendees optional_attendees resources conflicting_meeting_count adjacent_meeting_count
15
+ conflicting_meetings adjacent_meetings duration time_zone appointment_reply_time appointment_sequence_number
16
+ appointment_state recurrence first_occurrence last_occurrence modified_occurrences deleted_occurrences
17
+ meeting_time_zone start_time_zone end_time_zone conference_type allow_new_time_proposal is_online_meeting
18
+ meeting_workspace_url net_show_url effective_rights last_modified_name last_modified_time is_associated
19
+ web_client_read_form_query_string web_client_edit_form_query_string conversation_id unique_body
20
+ }.map(&:to_sym).freeze
21
+
22
+ # Returns a new CalendarItem template
23
+ def initialize(opts = {})
24
+ super opts.dup
25
+ end
26
+
27
+ # EWS CreateItem container
28
+ # @return [Hash]
29
+ def to_ews_create
30
+ structure = {}
31
+ structure[:message_disposition] = (draft ? 'SaveOnly' : 'SendAndSaveCopy')
32
+ structure[:send_meeting_invitations] = 'SendToNone'
33
+
34
+ if self.saved_item_folder_id
35
+ if self.saved_item_folder_id.kind_of?(Hash)
36
+ structure[:saved_item_folder_id] = saved_item_folder_id
37
+ else
38
+ structure[:saved_item_folder_id] = {id: saved_item_folder_id}
39
+ end
40
+ end
41
+
42
+ structure[:items] = [{calendar_item: to_ews_item}]
43
+ structure
44
+ end
45
+
46
+ # EWS Item hash
47
+ #
48
+ # Puts all known parameters in the required ordering and structure
49
+ # @return [Hash]
50
+ def to_ews_item
51
+ item_parameters = {}
52
+ PARAMETERS.each do |key|
53
+ if !(value = self.send(key)).nil?
54
+
55
+ # Convert non duplicable values to String
56
+ case value
57
+ when NilClass, FalseClass, TrueClass, Symbol, Numeric
58
+ value = value.to_s
59
+ end
60
+
61
+ # Convert attributes
62
+ case key
63
+ when :start, :end
64
+ item_parameters[key] = {text: value.respond_to?(:iso8601) ? value.iso8601 : value}
65
+ when :body
66
+ item_parameters[key] = {body_type: self.body_type || 'Text', text: value.to_s}
67
+ else
68
+ item_parameters[key] = value
69
+ end
70
+ end
71
+ end
72
+
73
+ item_parameters
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,24 @@
1
+ module Viewpoint::EWS
2
+ module Template
3
+ class ForwardItem < Message
4
+
5
+ # Format this object for EWS backend consumption.
6
+ def to_ews
7
+ ews_opts, msg = to_ews_basic
8
+ msg[:reference_item_id] = reference_item_id
9
+ msg[:new_body_content] = {text: new_body_content, body_type: new_body_type}
10
+ ews_opts.merge({items: [{forward_item: msg}]})
11
+ end
12
+
13
+ private
14
+
15
+
16
+ def init_defaults!
17
+ super
18
+ self.new_body_content ||= ''
19
+ self.new_body_type ||= 'Text'
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,73 @@
1
+ module Viewpoint::EWS
2
+ module Template
3
+ class Message < OpenStruct
4
+
5
+ def initialize(opts = {})
6
+ super opts.clone
7
+ init_defaults!
8
+ end
9
+
10
+ # Format this object for EWS backend consumption.
11
+ def to_ews
12
+ ews_opts, msg = to_ews_basic
13
+ ews_opts.merge({items: [{message: msg}]})
14
+ end
15
+
16
+ def has_attachments?
17
+ !(file_attachments.empty? && item_attachments.empty? && inline_attachments.empty?)
18
+ end
19
+
20
+
21
+ private
22
+
23
+
24
+ def init_defaults!
25
+ self.subject ||= nil
26
+ self.body ||= nil
27
+ self.body_type ||= 'Text'
28
+ self.importance ||= 'Normal'
29
+ self.draft ||= false
30
+ self.to_recipients ||= []
31
+ self.cc_recipients ||= []
32
+ self.bcc_recipients ||= []
33
+ self.file_attachments ||= []
34
+ self.item_attachments ||= []
35
+ self.inline_attachments ||= []
36
+ self.extended_properties ||= []
37
+ end
38
+
39
+ def to_ews_basic
40
+ ews_opts = {}
41
+ ews_opts[:message_disposition] = (draft ? 'SaveOnly' : 'SendAndSaveCopy')
42
+
43
+ if saved_item_folder_id
44
+ if saved_item_folder_id.kind_of?(Hash)
45
+ ews_opts[:saved_item_folder_id] = saved_item_folder_id
46
+ else
47
+ ews_opts[:saved_item_folder_id] = {id: saved_item_folder_id}
48
+ end
49
+ end
50
+
51
+ msg = {}
52
+ msg[:subject] = subject if subject
53
+ msg[:body] = {text: body, body_type: body_type} if body
54
+
55
+ msg[:importance] = importance if importance
56
+
57
+ to_r = to_recipients.collect{|r| {mailbox: {email_address: r}}}
58
+ msg[:to_recipients] = to_r unless to_r.empty?
59
+
60
+ cc_r = cc_recipients.collect{|r| {mailbox: {email_address: r}}}
61
+ msg[:cc_recipients] = cc_r unless cc_r.empty?
62
+
63
+ bcc_r = bcc_recipients.collect{|r| {mailbox: {email_address: r}}}
64
+ msg[:bcc_recipients] = bcc_r unless bcc_r.empty?
65
+
66
+ msg[:extended_properties] = extended_properties unless extended_properties.empty?
67
+
68
+ [ews_opts, msg]
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,25 @@
1
+ module Viewpoint::EWS
2
+ module Template
3
+ class ReplyToItem < Message
4
+
5
+ # Format this object for EWS backend consumption.
6
+ def to_ews
7
+ ews_opts, msg = to_ews_basic
8
+ msg[:reference_item_id] = reference_item_id
9
+ msg[:new_body_content] = {text: new_body_content, body_type: new_body_type}
10
+ ews_opts.merge({items: [{ews_type => msg}]})
11
+ end
12
+
13
+ private
14
+
15
+
16
+ def init_defaults!
17
+ super
18
+ self.new_body_content ||= ''
19
+ self.new_body_type ||= 'Text'
20
+ self.ews_type = :reply_to_item
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,74 @@
1
+ module Viewpoint::EWS
2
+ module Template
3
+ # Template for creating Tasks
4
+ # @see http://msdn.microsoft.com/en-us/library/exchange/aa564765.aspx
5
+ class Task < OpenStruct
6
+
7
+ # Available parameters with the required ordering
8
+ PARAMETERS = %w{mime_content item_id parent_folder_id item_class subject sensitivity body attachments
9
+ date_time_received size categories in_reply_to is_submitted is_draft is_from_me is_resend
10
+ is_unmodified internet_message_headers date_time_sent date_time_created response_objects
11
+ reminder_due_by reminder_is_set reminder_minutes_before_start display_cc display_to
12
+ has_attachments extended_property culture actual_work assigned_time billing_information
13
+ change_count companies complete_date contacts delegation_state delegator due_date
14
+ is_assignment_editable is_complete is_recurring is_team_task mileage owner percent_complete
15
+ recurrence start_date status status_description total_work effective_rights last_modified_name
16
+ last_modified_time is_associated web_client_read_form_query_string
17
+ web_client_edit_form_query_string conversation_id unique_body
18
+ }.map(&:to_sym).freeze
19
+
20
+ # Returns a new Task template
21
+ def initialize(opts = {})
22
+ super opts.dup
23
+ end
24
+
25
+ # EWS CreateItem container
26
+ # @return [Hash]
27
+ def to_ews_create
28
+ structure = {}
29
+
30
+ if self.saved_item_folder_id
31
+ if self.saved_item_folder_id.kind_of?(Hash)
32
+ structure[:saved_item_folder_id] = saved_item_folder_id
33
+ else
34
+ structure[:saved_item_folder_id] = {id: saved_item_folder_id}
35
+ end
36
+ end
37
+
38
+ structure[:items] = [{task: to_ews_item}]
39
+ structure
40
+ end
41
+
42
+ # EWS Item hash
43
+ #
44
+ # Puts all known parameters in the required ordering and structure
45
+ # @return [Hash]
46
+ def to_ews_item
47
+ item_parameters = {}
48
+ PARAMETERS.each do |key|
49
+ if !(value = self.send(key)).nil?
50
+
51
+ # Convert non duplicable values to String
52
+ case value
53
+ when NilClass, FalseClass, TrueClass, Symbol, Numeric
54
+ value = value.to_s
55
+ end
56
+
57
+ # Convert attributes
58
+ case key
59
+ when :start_date, :due_date
60
+ item_parameters[key] = {text: value.respond_to?(:iso8601) ? value.iso8601 : value}
61
+ when :body
62
+ item_parameters[key] = {body_type: self.body_type || 'Text', text: value.to_s}
63
+ else
64
+ item_parameters[key] = value
65
+ end
66
+ end
67
+ end
68
+
69
+ item_parameters
70
+ end
71
+
72
+ end
73
+ end
74
+ end
data/lib/ews/types.rb ADDED
@@ -0,0 +1,194 @@
1
+ module Viewpoint::EWS
2
+ module Types
3
+ include Viewpoint::StringUtils
4
+
5
+ KEY_PATHS = {
6
+ extended_properties: [:extended_property],
7
+ }
8
+ KEY_TYPES = {
9
+ extended_properties: :build_extended_properties,
10
+ }
11
+ KEY_ALIAS = {}
12
+
13
+ attr_reader :ews_item
14
+
15
+ # @param [SOAP::ExchangeWebService] ews the EWS reference
16
+ # @param [Hash] ews_item the EWS parsed response document
17
+ def initialize(ews, ews_item)
18
+ @ews = ews
19
+ @ews_item = ews_item
20
+ @shallow = true
21
+ @frozen = false
22
+ end
23
+
24
+ def method_missing(method_sym, *arguments, &block)
25
+ if method_keys.include?(method_sym)
26
+ type_convert( method_sym, resolve_method(method_sym) )
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ def to_s
33
+ "#{self.class.name}: EWS METHODS: #{self.ews_methods.sort.join(', ')}"
34
+ end
35
+
36
+ def frozen?
37
+ @frozen
38
+ end
39
+
40
+ # @param ronly [Boolean] true to freeze
41
+ def freeze!
42
+ @frozen = true
43
+ end
44
+
45
+ def unfreeze!
46
+ @frozen = false
47
+ end
48
+
49
+ def shallow?
50
+ @shallow
51
+ end
52
+
53
+ def mark_deep!
54
+ @shallow = false
55
+ end
56
+
57
+ def auto_deepen?
58
+ ews.auto_deepen
59
+ end
60
+
61
+ def deepen!
62
+ if shallow?
63
+ self.get_all_properties!
64
+ @shallow = false
65
+ true
66
+ end
67
+ end
68
+ alias_method :enlighten!, :deepen!
69
+
70
+ # @see http://www.ruby-doc.org/core/classes/Object.html#M000333
71
+ def respond_to?(method_sym, include_private = false)
72
+ if method_keys.include?(method_sym)
73
+ true
74
+ else
75
+ super
76
+ end
77
+ end
78
+
79
+ def methods(include_super = true)
80
+ super + ews_methods
81
+ end
82
+
83
+ def ews_methods
84
+ key_paths.keys + key_alias.keys
85
+ end
86
+
87
+ protected # things like OutOfOffice need protected level access
88
+
89
+ def ews
90
+ @ews
91
+ end
92
+
93
+ private
94
+
95
+ def key_paths
96
+ KEY_PATHS
97
+ end
98
+
99
+ def key_types
100
+ KEY_TYPES
101
+ end
102
+
103
+ def key_alias
104
+ KEY_ALIAS
105
+ end
106
+
107
+ def class_by_name(cname)
108
+ if(cname.instance_of? Symbol)
109
+ cname = camel_case(cname)
110
+ end
111
+ Viewpoint::EWS::Types.const_get(cname)
112
+ end
113
+
114
+ def type_convert(key,str)
115
+ begin
116
+ key = key_alias[key] || key
117
+ if key_types[key]
118
+ key_types[key].is_a?(Symbol) ? method(key_types[key]).call(str) : key_types[key].call(str)
119
+ else
120
+ str
121
+ end
122
+ rescue
123
+ nil
124
+ end
125
+ end
126
+
127
+ def resolve_method(method_sym)
128
+ begin
129
+ resolve_key_path(@ews_item, method_path(method_sym))
130
+ rescue
131
+ if shallow?
132
+ if frozen?
133
+ raise EwsFrozenObjectError, "Could not resolve :#{method_sym} on frozen object."
134
+ elsif auto_deepen?
135
+ enlighten!
136
+ retry
137
+ else
138
+ if !auto_deepen?
139
+ if ews.no_auto_deepen_behavior == :raise
140
+ raise EwsMinimalObjectError, "Could not resolve :#{method_sym}. #auto_deepen set to false"
141
+ else
142
+ nil
143
+ end
144
+ else
145
+ end
146
+ end
147
+ else
148
+ nil
149
+ end
150
+ end
151
+ end
152
+
153
+ def resolve_key_path(hsh, path)
154
+ k = path.first
155
+ return hsh[k] if path.length == 1
156
+ resolve_key_path(hsh[k],path[1..-1])
157
+ end
158
+
159
+ def method_keys
160
+ key_paths.keys + key_alias.keys
161
+ end
162
+
163
+ # Resolve the method path with or without an alias
164
+ def method_path(sym)
165
+ key_paths[key_alias[sym] || sym]
166
+ end
167
+
168
+ def build_extended_properties(eprops)
169
+ h = {}
170
+ # todo
171
+ # the return pattern seems broken in some cases,
172
+ # probably needs fixing via a dedicated response parser
173
+ eprops.each do |e|
174
+ if e.size == 1
175
+ e[:elems].each_cons(2) do |k,v|
176
+ key = k[:extended_field_u_r_i][:attribs][:property_name].downcase.to_sym
177
+ val = v[:value][:text]
178
+ h.store(key,val)
179
+ end
180
+ elsif e.size == 2
181
+ e[1].each_cons(2) do |k,v|
182
+ key = k[:extended_field_u_r_i][:attribs][:property_name].downcase.to_sym
183
+ val = v[:value][:text]
184
+ h.store(key,val)
185
+ end
186
+ else
187
+ raise EwsMinimalObjectError, "Not prepared to deal with elements greater than 2"
188
+ end
189
+ end
190
+ h
191
+ end
192
+
193
+ end
194
+ end