jiraSOAP 0.4.0 → 0.5.0

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.
@@ -0,0 +1,26 @@
1
+ require 'jiraSOAP/entities/abstract'
2
+ require 'jiraSOAP/entities/read_only'
3
+ require 'jiraSOAP/entities/field_value'
4
+ require 'jiraSOAP/entities/user'
5
+
6
+ require 'jiraSOAP/entities/avatar'
7
+ require 'jiraSOAP/entities/comment'
8
+ require 'jiraSOAP/entities/issue'
9
+
10
+ require 'jiraSOAP/entities/filter'
11
+ require 'jiraSOAP/entities/version'
12
+ require 'jiraSOAP/entities/attachments'
13
+ require 'jiraSOAP/entities/project'
14
+ require 'jiraSOAP/entities/schemes'
15
+ require 'jiraSOAP/entities/issue_properties'
16
+
17
+ module JIRA
18
+ # Represents a field mapping.
19
+ class Field < JIRA::NamedEntity
20
+ end
21
+
22
+ # Represents a component description for a project. It does not include
23
+ # the component lead.
24
+ class Component < JIRA::NamedEntity
25
+ end
26
+ end
@@ -0,0 +1,95 @@
1
+ module JIRA
2
+
3
+ # @abstract
4
+ # The base class for all JIRA objects that can be created by the server.
5
+ class Entity
6
+
7
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
8
+ # @return [JIRA::Entity]
9
+ def self.new_with_xml_fragment(frag)
10
+ entity = allocate
11
+ entity.initialize_with_xml_fragment frag
12
+ entity
13
+ end
14
+
15
+ # @raise [NotImplementedError] this method MUST be implemented in a non
16
+ # abstract descendant
17
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
18
+ def initialize_with_xml_fragment(frag)
19
+ raise NotImplementedError.new, 'Subclasses should override and implement'
20
+ end
21
+ end
22
+
23
+ # @abstract
24
+ # Most JIRA objects will have an id attribute as a unique identifier in
25
+ # their area.
26
+ class DynamicEntity < JIRA::Entity
27
+
28
+ # @return [String] usually holds a numerical value but for consistency with
29
+ # with id's from custom fields this attribute is always a String
30
+ attr_accessor :id
31
+
32
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
33
+ def initialize_with_xml_fragment(frag)
34
+ @id = (frag/'id').to_s
35
+ end
36
+ end
37
+
38
+ # @abstract
39
+ # Many JIRA objects include a name.
40
+ class NamedEntity < JIRA::DynamicEntity
41
+
42
+ # @return [String] a plain language name
43
+ attr_accessor :name
44
+
45
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
46
+ def initialize_with_xml_fragment(frag)
47
+ super frag
48
+ @name = (frag/'name').to_s
49
+ end
50
+ end
51
+
52
+ # @abstract
53
+ # Several JIRA objects include a short description.
54
+ class DescribedEntity < JIRA::NamedEntity
55
+
56
+ # @return [String] usually a short blurb
57
+ attr_accessor :description
58
+
59
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
60
+ def initialize_with_xml_fragment(frag)
61
+ super frag
62
+ @description = (frag/'description').to_s
63
+ end
64
+ end
65
+
66
+ # @abstract
67
+ # Represents a scheme used by the server. Not very useful for the sake of the
68
+ # API; a more useful case might be if you wanted to emulate the server's
69
+ # behaviour.
70
+ class Scheme < JIRA::DescribedEntity
71
+ # Schemes that inherit this class will have to be careful when they try
72
+ # to encode the scheme type in an xml message.
73
+ # @return [String]
74
+ def type
75
+ self.class.to_s
76
+ end
77
+ end
78
+
79
+ # @abstract
80
+ # A common base for most issue properties. Core issue properties have
81
+ # an icon to go with them to help identify properties of issues more
82
+ # quickly.
83
+ class IssueProperty < JIRA::DescribedEntity
84
+
85
+ # @return [URL] A NSURL on MacRuby and a URI::HTTP object in CRuby
86
+ attr_accessor :icon
87
+
88
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
89
+ def initialize_with_xml_fragment(frag)
90
+ super frag
91
+ @icon = (frag/'icon').to_url
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,35 @@
1
+ module JIRA
2
+
3
+ # Only contains the metadata for an attachment. The URI for an attachment
4
+ # appears to be of the form
5
+ # "{JIRA::JIRAService.endpoint_url}/secure/attachment/{#id}/{#filename}"
6
+ class AttachmentMetadata < JIRA::NamedEntity
7
+
8
+ # @return [String]
9
+ attr_accessor :author
10
+
11
+ # @return [Time]
12
+ attr_accessor :create_date
13
+
14
+ # @return [String]
15
+ attr_accessor :filename
16
+
17
+ # @return [Fixnum] measured in bytes
18
+ attr_accessor :file_size
19
+
20
+ # @return [String]
21
+ attr_accessor :mime_type
22
+
23
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
24
+ def initialize_with_xml_fragment(frag)
25
+ super frag
26
+ @author, @filename, @mime_type, @file_size, @create_date =
27
+ frag.nodes( ['author', :to_s],
28
+ ['filename', :to_s],
29
+ ['mimetype', :to_s],
30
+ ['filesize', :to_i],
31
+ ['created', :to_date] )
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,36 @@
1
+ module JIRA
2
+
3
+ # Contains a base64 encoded avatar image and metadata about the avatar.
4
+ class Avatar < JIRA::DynamicEntity
5
+
6
+ # @return [String]
7
+ attr_accessor :owner
8
+
9
+ # @return [String] the place where the avatar is used
10
+ attr_accessor :type
11
+
12
+ # @return [String]
13
+ attr_accessor :mime_type
14
+
15
+ # @return [String]
16
+ attr_accessor :base64_data
17
+
18
+ # @return [boolean] indicates if the image is the system default
19
+ attr_accessor :system
20
+
21
+ # @return [boolean] true if avatar is the default system avatar, else false
22
+ def system?; @system; end
23
+
24
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
25
+ def initialize_with_xml_fragment(frag)
26
+ super frag
27
+ @owner, @type, @mime_type, @base64_data, @system =
28
+ frag.nodes( ['owner', :to_s],
29
+ ['type', :to_s],
30
+ ['contentType', :to_s],
31
+ ['base64Data', :to_s],
32
+ ['system', :to_boolean] )
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,54 @@
1
+ module JIRA
2
+
3
+ # Contains a comments body and its metadata.
4
+ class Comment < JIRA::DynamicEntity
5
+
6
+ # @return [String]
7
+ attr_accessor :original_author
8
+
9
+ # @return [String]
10
+ attr_accessor :role_level
11
+
12
+ # @return [String]
13
+ attr_accessor :group_level
14
+
15
+ # @return [String]
16
+ attr_accessor :body
17
+
18
+ # @return [Time]
19
+ attr_accessor :create_date
20
+
21
+ # @return [Time]
22
+ attr_accessor :last_updated
23
+
24
+ # @return [String]
25
+ attr_accessor :update_author
26
+
27
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
28
+ def initialize_with_xml_fragment(frag)
29
+ super frag
30
+ @original_author, @body, @group_level, @role_level,
31
+ @update_author, @create_date, @last_updated =
32
+ frag.nodes( ['author', :to_s],
33
+ ['body', :to_s],
34
+ ['groupLevel', :to_s],
35
+ ['roleLevel', :to_s],
36
+ ['updateAuthor', :to_s],
37
+ ['created', :to_date],
38
+ ['updated', :to_date] )
39
+ end
40
+
41
+ # @todo make this method shorter
42
+ # @param [Handsoap::XmlMason::Node] msg
43
+ # @return [Handsoap::XmlMason::Node]
44
+ def soapify_for(msg)
45
+ msg.add 'id', @id
46
+ msg.add 'author', @original_author
47
+ msg.add 'body', @body
48
+ msg.add 'groupLevel', @group_level
49
+ msg.add 'roleLevel', @role_level
50
+ msg.add 'updateAuthor', @update_author
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,73 @@
1
+ module JIRA
2
+
3
+ # A structure that is a bit of a hack. It is essentially just a key-value pair
4
+ # that is used by {RemoteAPI#update_issue}.
5
+ class FieldValue
6
+
7
+ # @return [String] the name for regular fields, and the id for custom fields
8
+ attr_accessor :field_name
9
+
10
+ # @return [[String,Time,URL,nil]] Whatever the type, just make sure it is
11
+ # wrapped in an array.
12
+ attr_accessor :values
13
+
14
+ # @param [String] field_name
15
+ # @param [Array] values
16
+ def initialize(field_name = nil, values = nil)
17
+ @field_name = field_name
18
+ @values = values
19
+ end
20
+
21
+ # @todo soapify properly for custom objects (JIRA module).
22
+ # @param [Handsoap::XmlMason::Node] message the node to add the object to
23
+ # @param [String] label name for the tags that wrap the message
24
+ # @return [Handsoap::XmlMason::Element]
25
+ def soapify_for(message, label = 'fieldValue')
26
+ message.add label do |message|
27
+ message.add 'id', @field_name
28
+ message.add_simple_array 'values', @values unless @values.nil?
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+ # Represents an instance of a custom field (with values). This object is used
35
+ # as a member of {JIRA::Issue} objects.
36
+ #
37
+ # The structure of this class resembles JIRA::FieldValue, it is different
38
+ # in that @values will always be stored as an Array of String objects for
39
+ # custom fields and a field value is more flexible. You can expect the classes
40
+ # to merge in the near future.
41
+ # @todo see if @key is always nil from the server, maybe we can remove it
42
+ # @todo merge this class with JIRA::FieldValue
43
+ class CustomFieldValue < JIRA::DynamicEntity
44
+
45
+ # @return [String]
46
+ attr_accessor :key
47
+
48
+ # @return [[String]]
49
+ attr_accessor :values
50
+
51
+ # @note careful, value of id is actually customfieldId
52
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
53
+ def initialize_with_xml_fragment(frag)
54
+ @id, @key, @values =
55
+ frag.nodes( ['customfieldId', :to_s],
56
+ ['key', :to_s],
57
+ ['values/*', :to_ss] )
58
+ end
59
+
60
+ # Generate a SOAP message fragment for the object.
61
+ # @param [Handsoap::XmlMason::Node] msg SOAP message to add the object to
62
+ # @param [String] label tag name used in wrapping tags
63
+ # @return [Handsoap::XmlMason::Element]
64
+ def soapify_for(msg, label = 'customFieldValues')
65
+ msg.add label do |submsg|
66
+ submsg.add 'customfieldId', @id
67
+ submsg.add 'key', @key
68
+ submsg.add_simple_array 'values', @values
69
+ end
70
+ end
71
+ end
72
+
73
+ end
@@ -0,0 +1,26 @@
1
+ module JIRA
2
+
3
+ # Represents a filter, but does not seem to include the filters JQL query.
4
+ # @todo find out what @project is supposed to be for
5
+ class Filter < JIRA::DescribedEntity
6
+
7
+ # @return [String]
8
+ attr_accessor :author
9
+
10
+ # @return [String]
11
+ attr_accessor :project
12
+
13
+ # @return [nil]
14
+ attr_accessor :xml
15
+
16
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
17
+ def initialize_with_xml_fragment(frag)
18
+ super frag
19
+ @author, @project, @xml =
20
+ frag.nodes( ['author', :to_s],
21
+ ['project', :to_s],
22
+ ['xml', :to_s] )
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,166 @@
1
+ module JIRA
2
+
3
+ # Contains most of the data and metadata for a JIRA issue, but does
4
+ # not contain the {JIRA::Comment}'s or {JIRA::AttachmentMetadata}.
5
+ #
6
+ # This class is easily the most convoluted structure in the API, and will
7
+ # likely be the greatest source of bugs. The irony of the situation is that
8
+ # this structure is also the most critical to have in working order.
9
+ #
10
+ # Issues with an UNRESOLVED status will have nil for the value of @resolution.
11
+ class Issue < JIRA::DynamicEntity
12
+
13
+ # @return [String]
14
+ attr_accessor :key
15
+
16
+ # @return [String]
17
+ attr_accessor :summary
18
+
19
+ # @return [String]
20
+ attr_accessor :description
21
+
22
+ # @return [String]
23
+ attr_accessor :type_id
24
+
25
+ # @return [Time]
26
+ attr_accessor :last_updated
27
+
28
+ # @return [Fixnum]
29
+ attr_accessor :votes
30
+
31
+ # @return [String]
32
+ attr_accessor :status_id
33
+
34
+ # @return [String]
35
+ attr_accessor :assignee_name
36
+
37
+ # @return [String]
38
+ attr_accessor :reporter_name
39
+
40
+ # @return [String]
41
+ attr_accessor :priority_id
42
+
43
+ # @return [String]
44
+ attr_accessor :project_name
45
+
46
+ # @return [[JIRA::Version]]
47
+ attr_accessor :affects_versions
48
+
49
+ # @return [Time]
50
+ attr_accessor :create_date
51
+
52
+ # @return [Time]
53
+ attr_accessor :due_date
54
+
55
+ # @return [[JIRA::Version]]
56
+ attr_accessor :fix_versions
57
+
58
+ # @return [String]
59
+ attr_accessor :resolution_id
60
+
61
+ # @return [String]
62
+ attr_accessor :environment
63
+
64
+ # @return [[JIRA::Component]]
65
+ attr_accessor :components
66
+
67
+ # @return [[String]]
68
+ attr_accessor :attachment_names
69
+
70
+ # @return [[JIRA::CustomFieldValue]]
71
+ attr_accessor :custom_field_values
72
+
73
+ # @param [Handsoap::XmlQueryFront::NokogiriDriver] frag
74
+ def initialize_with_xml_fragment(frag)
75
+ super frag
76
+ @key, @summary, @description, @type_id, @status_id,
77
+ @assignee_name, @reporter_name, @priority_id, @project_name,
78
+ @resolution_id, @environment, @votes, @last_updated, @create_date,
79
+ @due_date, @affects_versions, @fix_versions, @components,
80
+ @custom_field_values, @attachment_names =
81
+ frag.nodes( ['key', :to_s],
82
+ ['summary', :to_s],
83
+ ['description', :to_s],
84
+ ['type', :to_s],
85
+ ['status', :to_s],
86
+ ['assignee', :to_s],
87
+ ['reporter', :to_s],
88
+ ['priority', :to_s],
89
+ ['project', :to_s],
90
+ ['resolution', :to_s],
91
+ ['environment', :to_s],
92
+ ['votes', :to_i],
93
+ ['updated', :to_date],
94
+ ['created', :to_date],
95
+ ['duedate', :to_date],
96
+ ['affectsVersions/*', :to_objects, JIRA::Version],
97
+ ['fixVersions/*', :to_objects, JIRA::Version],
98
+ ['components/*', :to_objects, JIRA::Component],
99
+ ['customFieldValues/*', :to_objects, JIRA::CustomFieldValue],
100
+ ['attachmentNames/*', :to_ss] )
101
+ end
102
+
103
+ # Generate the SOAP message fragment for an issue. Can you spot the oddities
104
+ # and inconsistencies? (hint: there are many).
105
+ #
106
+ # We don't bother including fields that are ignored. I tried to only
107
+ # ignore fields that will never be needed at creation time, but I may have
108
+ # messed up.
109
+ #
110
+ # We don't wrap the whole thing in 'issue' tags for
111
+ # {#RemoteAPI#create_issue_with_issue} calls; this is an inconsistency in the
112
+ # way jiraSOAP works and may need to be worked around for other {RemoteAPI}
113
+ # methods.
114
+ #
115
+ # Servers only seem to accept issues if components/versions are just ids
116
+ # and do not contain the rest of the {JIRA::Component}/{JIRA::Version}
117
+ # structure.
118
+ #
119
+ # To get the automatic assignee we pass '-1' as the value for @assignee.
120
+ #
121
+ # Passing an environment/due date field with a value of nil causes the
122
+ # server to complain about the formatting of the message.
123
+ # @todo see if we can use the simple and complex array builders
124
+ # @todo make this method shorter
125
+ # @param [Handsoap::XmlMason::Node] msg message the node to add the object to
126
+ def soapify_for(msg)
127
+ #might be going away, since it appears to have no effect at creation time
128
+ msg.add 'reporter', @reporter_name unless @reporter.nil?
129
+
130
+ msg.add 'priority', @priority_id
131
+ msg.add 'type', @type_id
132
+ msg.add 'project', @project_name
133
+
134
+ msg.add 'summary', @summary
135
+ msg.add 'description', @description
136
+
137
+ msg.add 'components' do |submsg|
138
+ (@components || []).each { |component|
139
+ submsg.add 'components' do |component_msg|
140
+ component_msg.add 'id', component.id
141
+ end
142
+ }
143
+ end
144
+ msg.add 'affectsVersions' do |submsg|
145
+ (@affects_versions || []).each { |version|
146
+ submsg.add 'affectsVersions' do |version_msg|
147
+ version_msg.add 'id', version.id
148
+ end
149
+ }
150
+ end
151
+ msg.add 'fixVersions' do |submsg|
152
+ (@fix_versions || []).each { |version|
153
+ submsg.add 'fixVersions' do |version_msg|
154
+ version_msg.add 'id', version.id end
155
+ }
156
+ end
157
+
158
+ msg.add 'assignee', (@assignee_name || '-1')
159
+ msg.add_complex_array 'customFieldValues', (@custom_field_values || [])
160
+
161
+ msg.add 'environment', @environment unless @environment.nil?
162
+ msg.add 'duedate', @due_date.xmlschema unless @due_date.nil?
163
+ end
164
+ end
165
+
166
+ end