1
|
|
|
require 'nokogiri' |
2
|
|
|
|
3
|
|
|
module VersiononeSdk |
4
|
|
|
class Update |
5
|
|
|
def initialize(oClient=nil) |
6
|
|
|
@oClient = oClient |
7
|
|
|
@dTagTypes = {simple_attribute: 1, single_relationship: 1, multi_relationship: 1} |
8
|
|
|
@sRelationships = 'BuildProjects,Owner,Parent,Schedule,Scheme,SecurityScope,Status,TestSuite' |
9
|
|
|
@dRelationships = Hash[@sRelationships.split(',').collect {|v| [v,1]}] |
10
|
|
|
end |
11
|
|
|
|
12
|
|
|
# Update a VersionOne asset. |
13
|
|
|
# |
14
|
|
|
# Params: |
15
|
|
|
# +sAssetType+:: A REST API asset type such as Scope, Epic, Story, Member, etc. The first part of the OID Token. |
16
|
|
|
# +sAssetOid+:: The numerical OID and the second part of the OID token. |
17
|
|
|
# +sName+:: Name of attribute to be updated. |
18
|
|
|
# +xxValues+:: values to be updated which can be a variety of formats. |
19
|
|
|
# +yTagType+:: A optional symbol to identify the type of attribute, e.g. |
20
|
|
|
# :simple_attribute, :single_relationship, or :multi_relationship |
21
|
|
|
def updateAsset(sAssetType=nil,sAssetOid=nil,sName=nil,xxValues=nil,yTagType=nil) |
22
|
|
|
aValues = normalizeValues(xxValues) |
23
|
|
|
# Validate Tag Type |
24
|
|
|
yTagType = yTagType.to_sym if yTagType.is_a?(String) |
25
|
|
|
|
26
|
|
|
unless yTagType.nil? |
27
|
|
|
unless @dTagTypes.key?(yTagType) |
28
|
|
|
raise ArgumentError, "E_BAD_TAG_TYPE: [#{yTagType.to_s}]" |
29
|
|
|
end |
30
|
|
View Code Duplication |
else |
|
|
|
|
31
|
|
|
if sName.nil? || ! sName.kind_of?(String) |
32
|
|
|
raise ArgumentError, 'E_NO_ATTRIBUTE_NAME' |
33
|
|
|
elsif @dRelationships.key?(sName) |
34
|
|
|
aValues.each do |dValue| |
35
|
|
|
sAct = dValue[:act] |
36
|
|
|
if sAct == 'set' |
37
|
|
|
yTagType = :single_relationship |
38
|
|
|
elsif sAct == 'add' || sAct == 'remove' |
39
|
|
|
yTagType = :multi_relationship |
40
|
|
|
else |
41
|
|
|
raise ArgumentError, "E_BAD_ACT: [#{sAct}]" |
42
|
|
|
end |
43
|
|
|
end |
44
|
|
|
else |
45
|
|
|
yTagType = :simple_attribute |
46
|
|
|
end |
47
|
|
|
end |
48
|
|
|
|
49
|
|
|
xBody \ |
50
|
|
|
= yTagType == :simple_attribute \ |
51
|
|
|
? getXmlBodyForSimpleAttributeUpdate(sName,aValues) \ |
52
|
|
|
: yTagType == :single_relationship \ |
53
|
|
|
? getXmlBodyForSingleRelationship(sName,aValues) \ |
54
|
|
|
: yTagType == :multi_relationship \ |
55
|
|
|
? getXmlBodyForMultiRelationship(sName,aValues) \ |
56
|
|
|
: nil |
57
|
|
|
|
58
|
|
|
unless xBody.nil? |
59
|
|
|
oFdRes = @oClient.oFaraday.post do |req| |
60
|
|
|
req.url getUrlForAssetTypeAndOid(sAssetType,sAssetOid) |
61
|
|
|
req.headers['Content-Type'] = 'application/xml' |
62
|
|
|
req.body = xBody |
63
|
|
|
end |
64
|
|
|
return oFdRes |
65
|
|
|
end |
66
|
|
|
|
67
|
|
|
return nil |
68
|
|
|
|
69
|
|
|
end |
70
|
|
|
|
71
|
|
|
private |
72
|
|
|
|
73
|
|
|
def normalizeValues(xxValues=nil) |
74
|
|
|
aValues = [] |
75
|
|
|
|
76
|
|
|
if xxValues.is_a?(String) |
77
|
|
|
aValues = [{value: xxValues, act: 'set'}] |
78
|
|
|
elsif xxValues.is_a?(Hash) |
79
|
|
|
aValues = [xxValues] |
80
|
|
|
elsif xxValues.is_a?(Array) |
81
|
|
|
xxValues.each do |xxSubValue| |
82
|
|
|
if xxSubValue.is_a?(String) |
83
|
|
|
sAct = xxValues.length > 1 ? 'add' : 'set' |
84
|
|
|
aValues.push({value: xxSubValue, act: sAct}) |
85
|
|
|
elsif xxSubValue.is_a?(Hash) |
86
|
|
|
aValues.push(xxSubValue) |
87
|
|
|
end |
88
|
|
|
end |
89
|
|
|
end |
90
|
|
|
|
91
|
|
|
return aValues |
92
|
|
|
end |
93
|
|
|
|
94
|
|
|
def getUrlForAssetTypeAndOid(sAssetType=nil,sAssetOid=nil) |
95
|
|
|
sUrl = File.join('/'[email protected],'rest-1.oauth.v1/Data',sAssetType,sAssetOid.to_s) |
96
|
|
|
return sUrl |
97
|
|
|
end |
98
|
|
|
|
99
|
|
View Code Duplication |
def getXmlBodyForSimpleAttributeUpdate(sName=nil,aValues=[]) |
|
|
|
|
100
|
|
|
sValue = aValues.length>0 && aValues[0].key?(:value) \ |
101
|
|
|
? aValues[0][:value] : nil |
102
|
|
|
oBuilder = Nokogiri::XML::Builder.new do |xml| |
103
|
|
|
xml.Asset { |
104
|
|
|
xml.Attribute(sValue, name: sName, act: 'set') |
105
|
|
|
} |
106
|
|
|
end |
107
|
|
|
return oBuilder.to_xml |
108
|
|
|
end |
109
|
|
|
|
110
|
|
View Code Duplication |
def getXmlBodyForSingleRelationship(sName=nil,aValues=[]) |
|
|
|
|
111
|
|
|
sValue = aValues.length>0 && aValues[0].key?(:value) \ |
112
|
|
|
? aValues[0][:value] : nil |
113
|
|
|
oBuilder = sValue.nil? \ |
114
|
|
|
? Nokogiri::XML::Builder.new { |xml| xml.Asset { \ |
115
|
|
|
xml.Relation(name: sName, act: 'set') |
116
|
|
|
} } |
117
|
|
|
: Nokogiri::XML::Builder.new { |xml| xml.Asset { \ |
118
|
|
|
xml.Relation(name: sName, act: 'set') { |
119
|
|
|
xml.Asset(idref: sValue) |
120
|
|
|
} |
121
|
|
|
} } |
122
|
|
|
return oBuilder.to_xml |
123
|
|
|
end |
124
|
|
|
|
125
|
|
|
def getXmlBodyForMultiRelationship(sName=nil,aValues=[]) |
126
|
|
|
oBuilder = aValues.length == 0 \ |
127
|
|
|
? Nokogiri::XML::Builder.new { |xml| xml.Asset { \ |
128
|
|
|
xml.Relation(name: sName, act: 'set') |
129
|
|
|
} } |
130
|
|
|
: Nokogiri::XML::Builder.new { |xml| xml.Asset { \ |
131
|
|
|
xml.Relation(name: sName) { |
132
|
|
|
aValues.each do |dValue| |
133
|
|
|
xml.Asset(idref: dValue[:value], act: dValue[:act]) |
134
|
|
|
end |
135
|
|
|
} |
136
|
|
|
} } |
137
|
|
|
return oBuilder.to_xml |
138
|
|
|
end |
139
|
|
|
end |
140
|
|
|
end |
141
|
|
|
|