@@ -36,8 +36,54 @@ def __init__(self, json=None, resource_id=None, **kwargs):
3636 if json is not None :
3737 self .from_json (json )
3838
39- def from_json (self , json ):
40- pass
39+ def parse_release_list (self , json_list , component_id = None ):
40+ """Parse a JSON list of releases, create according objects and add
41+ them to `container`."""
42+ releases = {}
43+ for release_json in json_list :
44+ release = Release (component_id = component_id )
45+ release .from_json (release_json )
46+ releases [release .id ] = release
47+ return releases
48+
49+ def parse_attachment_list (self , json_list , resources = []):
50+ """Parse a JSON list of releases, create according objects and add
51+ them to `container`."""
52+ attachments = {}
53+ for attachment_json in json_list :
54+ attachment = Attachment (resources = resources )
55+ attachment .from_json (attachment_json )
56+ attachments [attachment .id ] = attachment
57+ return attachments
58+
59+ def from_json (self , json , copy_attributes = list (), rename_attributes = {}):
60+ """`copy_attributes` will be copied as-is between this instance's
61+ attributes and JSON members. `rename_attributes` may contain a
62+ dictionary to map JSON attributes to instance attributes."""
63+ for key , value in json .items ():
64+ if key in copy_attributes :
65+ self .__setattr__ (key , value )
66+ elif key in rename_attributes :
67+ self .__setattr__ (rename_attributes [key ], value )
68+ elif key in ("_links" , "_embedded" ):
69+ for links_key , links_value in value .items ():
70+ if links_key == "sw360:component" :
71+ self .component_id = links_value ["href" ].split ("/" )[- 1 ]
72+ elif links_key == "sw360:attachments" :
73+ self .attachments = self .parse_attachment_list (
74+ links_value ,
75+ resources = [self ])
76+ elif links_key == "sw360:releases" :
77+ self .releases = self .parse_release_list (
78+ links_value ,
79+ component_id = self .id )
80+ elif links_key == "self" :
81+ self .id = links_value ["href" ].split ("/" )[- 1 ]
82+ else :
83+ self .details .setdefault (key , {})
84+ self .details [key ][links_key ] = links_value
85+ else :
86+ self .details [key ] = value
4187
4288
4389class Release (SW360Resource ):
@@ -82,28 +128,9 @@ def from_json(self, json):
82128 external ids which will be stored as-is in `details['externalIds'].
83129 Please note that this might change in future if better abstractions
84130 will be added in this Python library."""
85- attachments = []
86- for key , value in json .items ():
87- if key in ("name" , "version" , "downloadurl" ):
88- self .__setattr__ (key , value )
89- elif key in ("_links" , "_embedded" ):
90- for links_key , links_value in value .items ():
91- if links_key == "sw360:component" :
92- self .component_id = links_value ["href" ].split ("/" )[- 1 ]
93- elif links_key == "sw360:attachments" :
94- attachments = links_value
95- elif links_key == "self" :
96- self .id = links_value ["href" ].split ("/" )[- 1 ]
97- else :
98- self .details .setdefault (key , {})
99- self .details [key ][links_key ] = links_value
100- else :
101- self .details [key ] = value
102-
103- for attachment_json in attachments :
104- attachment = Attachment (resources = [self ])
105- attachment .from_json (attachment_json )
106- self .attachments [attachment .id ] = attachment
131+ super ().from_json (
132+ json ,
133+ copy_attributes = ("name" , "version" , "downloadurl" ))
107134
108135 def __repr__ (self ):
109136 """Representation string."""
@@ -158,20 +185,10 @@ def from_json(self, json):
158185 in the `details` instance attribute.
159186 Please note that this might change in future if better abstractions
160187 will be added in this Python library."""
161- for key , value in json .items ():
162- if key in ("filename" , "sha1" ):
163- self .__setattr__ (key , value )
164- elif key == "attachmentType" :
165- self .attachment_type = value
166- elif key == "_links" :
167- for links_key , links_value in value .items ():
168- if links_key == "self" :
169- self .id = links_value ["href" ].split ("/" )[- 1 ]
170- else :
171- self .details .setdefault (key , {})
172- self .details [key ][links_key ] = links_value
173- else :
174- self .details [key ] = value
188+ super ().from_json (
189+ json ,
190+ copy_attributes = ("filename" , "sha1" ),
191+ rename_attributes = {"attachmentType" : "attachment_type" })
175192
176193 def __repr__ (self ):
177194 """Representation string."""
@@ -228,37 +245,76 @@ def from_json(self, json):
228245 as-is in `details['_embedded']['sw360:vendors']` and
229246 `details['externalIds']. Please note that this might change in future
230247 if better abstractions will be added in this Python library."""
231- releases = []
232- attachments = []
233- for key , value in json .items ():
234- if key in ("name" , "description" , "homepage" ):
235- self .__setattr__ (key , value )
236- elif key == "componentType" :
237- self .component_type = value
238- elif key in ("_links" , "_embedded" ):
239- for links_key , links_value in value .items ():
240- if key == "_links" and links_key == "self" :
241- self .id = links_value ["href" ].split ("/" )[- 1 ]
242- elif links_key == "sw360:releases" :
243- releases = links_value
244- elif links_key == "sw360:attachments" :
245- attachments = links_value
246- else :
247- self .details .setdefault (key , {})
248- self .details [key ][links_key ] = links_value
249- else :
250- self .details [key ] = value
248+ super ().from_json (
249+ json ,
250+ copy_attributes = ("name" , "description" , "homepage" ),
251+ rename_attributes = {"componentType" : "component_type" })
251252
252- for release_json in releases :
253- release = Release (component_id = self .id )
254- release .from_json (release_json )
255- self .releases [release .id ] = release
253+ def __repr__ (self ):
254+ """Representation string."""
255+ return "<Component %s id:%s>" % (self .name , self .id )
256256
257- for attachment_json in attachments :
258- attachment = Attachment (resources = [self ])
259- attachment .from_json (attachment_json )
260- self .attachments [attachment .id ] = attachment
257+
258+ class Project (SW360Resource ):
259+ """A project is SW360 abstraction for a collection of software components
260+ used in a project/product. It can contain links to other `Project`s or
261+ `Release`s.
262+
263+ You can either create it from a SW360 `json` object or by specifying the
264+ details via the constructor parameters, see list below. Only the most
265+ important attributes are supported, rest hast be provided via `kwargs` and
266+ is stored in the `details` attribute of instances.
267+
268+ For JSON parsing, please read documentation of from_json() method.
269+
270+ :param json: create component from SW360 JSON object by calling from_json()
271+ :param project_id: id of the project (if exists in SW360 already)
272+ :param name: name of the project
273+ :param version: version of the project
274+ :param description: short description for project
275+ :param visibility: project visibility in SW360, one of "PRIVATE",
276+ "ME_AND_MODERATORS", "BUISNESSUNIT_AND_MODERATORS",
277+ "EVERYONE"
278+ :param project_type: one of "CUSTOMER", "INTERNAL", "PRODUCT", "SERVICE",
279+ "INNER_SOURCE"
280+ :param kwargs: additional project details as specified in the SW360 REST API
281+ :type json: SW360 JSON object
282+ :type project_id: string
283+ :type name: string
284+ :type version: string
285+ :type description: string
286+ :type visibility: string
287+ :type project_type: string
288+ :type kwargs: dictionary
289+ """
290+ def __init__ (self , json = None , project_id = None , name = None , version = None ,
291+ description = None , visibility = None , project_type = None ,
292+ ** kwargs ):
293+ self .releases = {}
294+
295+ self .name = name
296+ self .version = version
297+ self .description = description
298+ self .visibility = visibility
299+ self .project_type = project_type
300+ super ().__init__ (json , project_id , ** kwargs )
301+
302+ def from_json (self , json ):
303+ """Parse project JSON object from SW360 REST API. Information for
304+ its releases will be extracted, Release() objects created for them
305+ and stored in the `releases` instance attribue. Please note that
306+ the REST API will only provide basic information for the releases.
307+
308+ All details not directly supported by this class will be
309+ stored as-is in the `details` instance attribute. For now, this also
310+ includes linked projects and external ids. Please note that this might
311+ change in future if better abstractions will be added in this Python
312+ library."""
313+ super ().from_json (
314+ json ,
315+ copy_attributes = ("name" , "description" , "version" , "visibility" ),
316+ rename_attributes = {"projectType" : "project_type" })
261317
262318 def __repr__ (self ):
263319 """Representation string."""
264- return "<Component %s id:%s>" % (self .name , self .id )
320+ return "<Project %s id:%s>" % (self .name , self .id )
0 commit comments