Example on how to install Requirements Viewpoint, and how to import requirements from an Excel

Hello.

I would be very grateful if you could tell me how to install Requirements Viewpoint. In order to facilitate the connection between the two tools Capella and Excel, to be able to import the requirements in Capella from an Excel file.

best regards
Meziane HACHEMI

The general installation procedure is here, you’ll see the addon section just below: https://wiki.eclipse.org/Capella/Extensions/Installation_Guide#Installation_Procedures

Right now it is not possible to import Requirements from an excel file. What we support is import from a ReqIF file. There is probably a way to use groovy for Capella to import Requirements from an Excel file, but I have not tried it so I can’t help you, see this post: https://forum.mbse-capella.org/t/1104421/

It is probably now possible/easier to import requirements using an excel file using Python for Capella…

The easiest way to import requirements from an Excel file is the use of pyreqif, which enables the conversion to ReqIF. Some care should be taken in the column naming to match ReqIF standards. As an example the requirement identifier column header should be “IE PUID”. Using Python4Capella I am currently able to export requirements from Capella straight to Excel.

Seems great! Could you please share the script you made?

Hi Juan,
I made some modifications to the simplified API requirement.py, adding the implementation of some classes and getters/setters.
More in details, the following classes have been implemented:

  • Attribute
  • ReqIFElement
  • AbstractRelation
  • CapellaIncomingRelation
  • CapellaOutgoingRelation
  • AbstractType
  • RelationType

The script for exporting requirements to Excel partially depends upon those modifications.
Please find attached the updated requirement.py and the export to Excel script. Some tuning to generalize the export script is needed.

Export_Requirements_to_xlsx.py (7.8 KB)
requirement.py (8.4 KB)

Pier Giorgio

1 Like

Hello @pge62
Thank you for your contribution to Python4Capella :slight_smile:

Hello @pge62 ,
It looks like there is no modification in the simplified api requirement.py

Hello Sophie,
I apologize, but requirement.py has been modified, by adding new classes and implementing methods which were missing in Python4Capella addon.
Please find attached the updated script.
requirement.py (14.3 KB)

Please find below diffs

Pier Giorgio

--- requirement.py	2022-06-16 17:48:10.101859900 +0200
+++ /mnt/c/Users/piergiorgio.esposito/ws/capella_ws/Python4Capella/simplified_api/requirement.py	2021-12-13 10:06:22.000000000 +0100
@@ -161,15 +161,6 @@
         """
         """
         self.get_java_object().setReqIFChapterName(value)
-    def get_description(self):
-        """
-        """
-        return self.get_java_object().getReqIFDescription()
-    def set_description(self, value):
-        """
-        """
-        self.get_java_object().setReqIFDescription(value)
-        
     def get_prefix(self):
         """
         """
@@ -188,27 +179,11 @@
         self.get_java_object().setReqIFText(value)
     def get_all_attributes(self):
         """
+        status: KO
         """
-        res = []
-        for child in self.get_java_object().eContents():
-            specific_cls_name = child.eClass().getName()
-            if (specific_cls_name == "StringValueAttribute") or \
-               (specific_cls_name == "IntegerValueAttribute") or \
-               (specific_cls_name == "EnumerationValueAttribute") or \
-               (specific_cls_name == "BooleanValueAttribute") or \
-               (specific_cls_name == "RealValueAttribute"):
-                res.append(Attribute(child))
-        return res
-                
+        raise AttributeError("TODO")
     def get_attribute(self, attributeName):
         """
-        """
-        for attr in self.get_all_attributes():
-            if attributeName == attr.get_definition().getReqIFLongName():
-                return attr
-        return None
-                                            
-        """
         status: KO
         """
         raise AttributeError("TODO")
@@ -247,12 +222,6 @@
                         res.append(specific_cls(capella_element))
         return res
 
-    def get_owned_relations(self):
-        """
-        status: OK
-        """
-        return create_e_list(self.java_object.getOwnedRelations(), AbstractRelation)
-
 class Folder(Requirement):
     """
     """
@@ -271,155 +240,3 @@
         return create_e_list(self.get_java_object().getOwnedRequirements(), Requirement)
 
 
-class Attribute(EObject):
-    """
-    """
-    def __init__(self, java_object = None):
-        """
-        """
-        if java_object is None:
-            JavaObject.__init__(self, create_e_object("http://www.polarsys.org/kitalpha/requirements", "Attribute"))
-        elif isinstance(java_object, Attribute):
-            JavaObject.__init__(self, java_object.get_java_object())
-        else:
-            JavaObject.__init__(self, java_object)
-    
-    def get_definition(self):
-        """
-        """
-        return self.get_java_object().getDefinition()
-    
-    def get_value(self):
-        """
-        """
-        return self.get_java_object().getValue()
-    
-class ReqIFElement(EObject):
-    """
-    """
-    def __init__(self, java_object = None):
-        """
-        """
-        if java_object is None:
-            JavaObject.__init__(self, create_e_object("http://www.polarsys.org/kitalpha/requirements", "ReqIFElement"))
-        elif isinstance(java_object, ReqIFElement):
-            JavaObject.__init__(self, java_object.get_java_object())
-        else:
-            JavaObject.__init__(self, java_object)
-            
-
-class AbstractRelation(ReqIFElement):
-    """
-    """
-    def __init__(self, java_object = None):
-        """
-        """
-        if java_object is None:
-            raise ValueError("No matching EClass for this type")
-        elif isinstance(java_object, AbstractRelation):
-            JavaObject.__init__(self, java_object.get_java_object())
-        else:
-            JavaObject.__init__(self, java_object)
-            
-    def get_relation_type(self):
-        """
-        """
-        return RelationType(self.get_java_object().getRelationType())
-    def set_relation_type(self, value):
-        """
-        """
-        self.get_java_object().setRelationType(value.get_java_object())
-
-class CapellaIncomingRelation(AbstractRelation):
-    """
-    """
-    def __init__(self, java_object = None):
-        if java_object is None:
-           JavaObject.__init__(self, create_e_object("http://www.polarsys.org/capella/requirements", "CapellaIncomingRelation"))
-        elif isinstance(java_object, CapellaIncomingRelation):
-            JavaObject.__init__(self, java_object.get_java_object())
-        else:
-            JavaObject.__init__(self, java_object)  
-    def set_source(self, value):
-        """
-        """
-        self.get_java_object().setSource(value.get_java_object())
-    def set_target(self, value):
-        """
-        """
-        self.get_java_object().setTarget(value.get_java_object())
-        
-
-class CapellaOutgoingRelation(AbstractRelation):
-    """
-    """
-    def __init__(self, java_object = None):
-        if java_object is None:
-           JavaObject.__init__(self, create_e_object("http://www.polarsys.org/capella/requirements", "CapellaOutgoingRelation"))
-        elif isinstance(java_object, CapellaOutgoingRelation):
-            JavaObject.__init__(self, java_object.get_java_object())
-        else:
-            JavaObject.__init__(self, java_object)  
-    def set_source(self, value):
-        """
-        """
-        self.get_java_object().setSource(value.get_java_object())
-    def set_target(self, value):
-        """
-        """
-        self.get_java_object().setTarget(value.get_java_object())
-
-
-class AbstractType(CapellaElement):
-    """
-    """
-    def __init__(self, java_object = None):
-        """
-        """
-        if java_object is None:
-            JavaObject.__init__(self, create_e_object("http://www.polarsys.org/kitalpha/requirements", "AbstractType"))
-        elif isinstance(java_object, AbstractType):
-            JavaObject.__init__(self, java_object.get_java_object())
-        else:
-            JavaObject.__init__(self, java_object)
-    
-class RelationType(AbstractType):
-    """
-    """
-    def __init__(self, java_object = None):
-        """
-        """
-        if java_object is None:
-            JavaObject.__init__(self, create_e_object("http://www.polarsys.org/kitalpha/requirements", "RelationType"))
-        elif isinstance(java_object, RelationType):
-            JavaObject.__init__(self, java_object.get_java_object())
-        else:
-            JavaObject.__init__(self, java_object)
-
-    @staticmethod
-    def get_relation_types(architecture):
-        """
-        """
-        res = []
-        for fld in architecture.get_java_object().eContents():
-            if fld.eClass().getName() == "CapellaTypesFolder":
-                for rel in fld.eContents():
-                    if rel.eClass().getName() == "RelationType":
-                        res.append(RelationType(rel))
-        
-        return res
-    
-    @staticmethod
-    def get_relation_type_by_name(architecture, name):
-        """
-        """
-        for rel in RelationType.get_relation_types(architecture):
-            if rel.get_name() == name:
-                return rel
-        return None
-    
-    def get_name(self):
-        """
-        """
-        return self.get_java_object().getReqIFLongName()
-        
2 Likes

I merged the pull request and made some changes. You can get the current version here.

Can you check if everything is still working on your side with this version ?
I changed the get_relation_type_by_name() to use the name and added get_relation_type_by_long_name() to filter on the long name.

I’m about to release a new version of Python4Capella and would like to make sure your contribution has been correctly merged.

1 Like

Hi Yvan,
I checked my python4capella scripts against the updated requirement.py API. I am currently using Python4Capella Release 2021-12-13. Is there any incompatibility of the new requirement.py vs such Python4Capella release?
I got the following exception with the new script.

Pier Giorgio

2022-09-20 14:51:28,388 - MainProcess - There was an exception while executing the Python Proxy on the Python Side.
Traceback (most recent call last):
  File "C:\Users\piergiorgio.esposito\Programmi\Capella-5.1.0\capella\plugins\org.eclipse.ease.lang.python.py4j_0.8.0.I202104091518\pysrc\ease_py4j_main.py", line 189, in runcode
    exec(compiled, self.locals)
  File "workspace://Python4PLT_GS/PLT_scripts/Clean_Trace_GSRD_to_logical_architecture.py", line 93, in <module>
  File "workspace://Python4PLT_GS/simplified_api/requirement.py", line 492, in get_relation_type_by_name
  File "workspace://Python4PLT_GS/simplified_api/requirement.py", line 463, in get_name
  File "C:\Users\piergiorgio.esposito\Programmi\Capella-5.1.0\capella\plugins\py4j-python_0.10.9.3-bnd-2odeag\src\py4j\java_gateway.py", line 1321, in __call__
    return_value = get_return_value(
  File "C:\Users\piergiorgio.esposito\Programmi\Capella-5.1.0\capella\plugins\py4j-python_0.10.9.3-bnd-2odeag\src\py4j\protocol.py", line 330, in get_return_value
    raise Py4JError(
py4j.protocol.Py4JError: An error occurred while calling o175754.getReqIFName. Trace:
py4j.Py4JException: Method getReqIFName([]) does not exist

Thank you for your feedback. Other things have changed but I don’t think it should impact this part of the API. I’ll check locally.

You should use get_relation_type_by_long_name() and get_relation_type_by_name() should not exists.

I replaced the method with get_relation_type_by_long_name() and it worked!

Thank you again for your contribution. I will now proceed with the release.