blob: 5062f95a88bc81d9f26de81eccc67748ecf8d79e [file] [log] [blame]
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Welcome to EASE Py4J Notebooks!\n",
"\n",
"\n",
"All the python code written is this notebook is executed by EASE Jupyter engine as the EASE Py4J engine would in a .py script.\n",
"It means that this web page is tighly connected to the eclipse session from which is was launched, and has access to all the Java functions exposed by EASE modules."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following code shows how to import UI EASE module and open an Eclipse Popup Dialog. (If you run this notebook in an external browser in full screen, switch back to eclipse to see it!)\n",
"You can find more information related to EASE [here](https://www.eclipse.org/ease/documentation/)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"ui_module = loadModule('/System/UI')\n",
"\n",
"ui_module.showInfoDialog(\"Hello Eclipse World!!\", \"Message from Jupyter\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Get the best of both worlds!!\n",
"The interesting thing is that you can combine Eclipse functionalities with Jupyter features.\n",
"For instance it's possible to create very simple GUIs with [ipywidgets](https://ipywidgets.readthedocs.io/en/latest/) and interact with eclipse objects.\n",
"\n",
"Remark : ipywidget doesn't work with eclipse internal web browser. The General/Web browser option should be set to \"External Browser\".\n",
"If not present in your Anaconda distribution, ipython widgets can be installed with the following command in Anaconda prompt:\n",
" \n",
" conda install ipywidgets"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "b9fb0616adc142098022d8c51f27b3c4",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Text(value='Hello Eclipse world from a widget!', description='message'), Button(descript…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from ipywidgets import interact_manual\n",
"\n",
"@interact_manual(message=\"Hello Eclipse world from a widget!\")\n",
"def open_popup_with_message(message):\n",
" ui_module.showInfoDialog(message, \"Message from Jupyter\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Hide python code in external scripts\n",
"Notice that the python code can be hidden in script files located in the workspace. That way only a single line EASE \"include\" statement is needed."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "a122cd1de6f04f7d9fe0fa4649ab55b3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Text(value='Hello Eclipse world from a script file!', description='message'), Button(des…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"include(\"workspace://PapyrusInJupyterExample/script/hello_world.py\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This following example shows how to create a new file in an eclipse project and open it in an eclipse editor. The file name is defined with an simple jupyter widget."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "05e0650d3eb946e18d8b7bac3dba1b9c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Text(value='example_file.txt', description='filename'), Text(value='Type your message he…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#required to access to the \"getFile\" function\n",
"res_module = loadModule(\"/System/Resources\")\n",
"\n",
"@interact_manual( filename=\"example_file.txt\", message=\"Type your message here\")\n",
"def create_and_open_file(filename, message):\n",
" path = \"workspace:///PapyrusInJupyterExample/\" + filename\n",
" file = res_module.getFile(path,True)\n",
" if (file is None):\n",
" file = res_module.createFile(path)\n",
" res_module.writeFile(file, message, 0, True)\n",
" \n",
" ui_module.showEditor(file)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Open Papyrus file from Jupyter\n",
"\n",
"Papyrus files can be directly opened with the \"System/UI/showEditor\" EASE function\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"papyrus_path = \"workspace://PapyrusInJupyterExample/PapyrusInJupyterExample.di\"\n",
"papyrus_editor =ui_module.showEditor(papyrus_path);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# EASE Papyrus module\n",
"\n",
"In addition to existing EASE Modeling modules such as Ecore, UML, SysML, Papyrus module provides functionalities helping to interact with a running papyrus session.\n",
"\n",
"\"getPapyrusModel\" helps to access to access to the root model element of papyrus file."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Root model name is : \n",
"PapyrusInJupyterExample\n"
]
}
],
"source": [
"papyrus_util = loadModule('/Modeling/PapyrusUtils');\n",
"root_model = papyrus_util.getPapyrusModel(papyrus_path)\n",
"\n",
"print('Root model name is : ')\n",
"print(root_model.getName())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively, you can use getPapyrusNamedElement to directly access by qualified name to any model elements located in an UML file."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"prop type is : \n",
"String\n"
]
}
],
"source": [
"prop = papyrus_util.getPapyrusNamedElement(papyrus_path, \"PapyrusInJupyterExample::sub_package2::Class3::Property1\")\n",
"\n",
"print('prop type is : ')\n",
"print(prop.getType().getName())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that once a model element is obtained, it can be used later as the context object parameter to access to other elements.\n",
"Moreover, the imported model elements can also be accessed easily by name."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml\n"
]
}
],
"source": [
"integer_type = papyrus_util.getPapyrusNamedElement(prop, \"PrimitiveTypes::Integer\")\n",
"\n",
"print(integer_type.eResource().getURI())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This following cell shows how to iterate over objects in a model and for instance collect packages qualified names."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['PapyrusInJupyterExample', 'PapyrusInJupyterExample::sub_package1', 'PapyrusInJupyterExample::sub_package2']\n"
]
}
],
"source": [
"\n",
"def get_all_packages(root_model):\n",
" packages_names = []\n",
" packages_names.append(root_model.getQualifiedName())\n",
" for element in root_model.allOwnedElements():\n",
" if (element.eClass().getName() == \"Package\"):\n",
" packages_names.append(element.getQualifiedName())\n",
" return packages_names\n",
"\n",
"packages = get_all_packages(root_model)\n",
"\n",
"print(packages)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Modifying model elements from EASE or Jupyter\n",
"\n",
"Modification of Papyrus in memory model elements should be done in transactions integrated in its Undo/Redo framework.\n",
"We provide a `papyrun`python function to do it easily. This function is defined in a script packaged in a plugin:\n",
"\n",
"`include(\"platform:/plugin/org.eclipse.papyrus.ease/scripts/python/papyrusutils.py\")`\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"#we redo necessary loadModule just in case previous cells have not been executed\n",
"ui_module = loadModule('/System/UI')\n",
"papyrus_util = loadModule('/Modeling/PapyrusUtils');\n",
"\n",
"papyrus_path = \"workspace://PapyrusInJupyterExample/PapyrusInJupyterExample.di\"\n",
"papyrus_editor =ui_module.showEditor(papyrus_path);\n",
"\n",
"\n",
"#we import the papyrusutils.py script which defined papyrus function\n",
"include(\"platform:/plugin/org.eclipse.papyrus.ease/scripts/python/papyrusutils.py\")\n",
"\n",
"papyrus =ui_module.showEditor(papyrus_path);\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['pAPYRUSiNjUPYTEReXAMPLE', 'pAPYRUSiNjUPYTEReXAMPLE::sub_package1', 'pAPYRUSiNjUPYTEReXAMPLE::sub_package2']\n"
]
}
],
"source": [
"def swap_name_case(named_element) :\n",
" new_name = named_element.getName().swapcase()\n",
" named_element.setName(new_name)\n",
" return new_name\n",
"\n",
"root_model = getPapyrusModel(papyrus_path)\n",
"\n",
"#the first parameter of papyrus is the function name you want to execute\n",
"#following parameters are the arguments you want to pass to the function\n",
"new_name = papyrun(swap_name_case, root_model)\n",
"\n",
"print(get_all_packages(root_model))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Have a look at your papyrus model! Root model name has changed. You can undo the modification with ctrl + z."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following example combines a jupyter widget with a function modifying the model.\n",
"\n",
"Notice that the modification can be undone in Papyrus with the Undo/Redo framework (crtl + z)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6182ff1ec9364b5db17c442a39567e7e",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Dropdown(description='package', options={'PapyrusInJupyterExample': JavaObject id=o144, …"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from ipywidgets import interact_manual\n",
"def create_class(package, name):\n",
" return package.createOwnedClass(name, False)\n",
"\n",
"#we create a map \n",
"package_dict = {}\n",
"for package_name in get_all_packages(root_model):\n",
" package_dict[package_name] = papyrus_util.getPapyrusNamedElement(root_model, package_name)\n",
"\n",
"\n",
"@interact_manual(package=package_dict , class_name = \"defaultName\")\n",
"def create_class_interact(package, class_name):\n",
" new_class = papyrun(create_class, package, class_name)\n",
" print('a new class is created in the model :' + new_class.getQualifiedName())\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Experimental unstable feature : creating diagrams"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In Papyrus, each palette element is identified with an unique ElementType ID.\n",
"\n",
"The function following function allows the emulation of the palette with a mouse :\n",
"\n",
"`createSemanticElementAndView(ElementTypeID, X, Y, Height, Width)`\n"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"#create diagram allows the creation of diagram\n",
"#first param is the container of the diagram\n",
"#second param is the label of the diagram (as in New Diagram menu)\n",
"#third param is the diagram name\n",
"papyrun(papyrus_util.createDiagram, root_model ,'Class Diagram', \"newDiagram\")\n",
"\n",
"\n",
"diTypes = org.eclipse.papyrus.uml.service.types.element.UMLDIElementTypes\n",
"\n",
"def createClasses():\n",
" \n",
" results = []\n",
" results.append(createSemanticElementAndView(diTypes.CLASS_SHAPE.getId(), 0,300,200, 200))\n",
" results.append(createSemanticElementAndView(diTypes.CLASS_SHAPE.getId(), 400,300, 200, 200))\n",
" results.append(createSemanticElementAndView(diTypes.CLASS_SHAPE.getId(), 200,0 , 200, 200))\n",
" return results\n",
"\n",
"classes = papyrun(createClasses)\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"def createLinks(classes):\n",
" class1 = classes[0]\n",
" class2 = classes[1]\n",
" class3 = classes[2]\n",
" \n",
" #the result of a createSemanticElementAndView is an Handler which \n",
" #gives access to both the semantic element and the view with the\n",
" #getElement and the getView methods\n",
" class1.getElement().setName(\"ClassExample1\")\n",
" \n",
" for i in range(3):\n",
" \n",
" result = createSemanticElementAndLinkView(diTypes.ASSOCIATION_COMPOSITE_DIRECTED_EDGE.getId(), \n",
" class1.getView(), 1.0 ,i/3+0.05, \n",
" class2.getView(),0.0,i/3+0.05)\n",
" \n",
" \n",
" createSemanticElementAndLinkView(diTypes.GENERALIZATION_EDGE.getId(), class1.getView(),0.5 ,0.0, class3.getView(),0.5,1.0)\n",
" createSemanticElementAndLinkView(diTypes.GENERALIZATION_EDGE.getId(), class2.getView(), 0.5 ,0.0, class3.getView(),0.5,1.0)\n",
" \n",
" \n",
"papyrun(createLinks, classes)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "EASE Py4j Python 3",
"language": "python",
"name": "ease_py4j_kernel"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": false,
"sideBar": false,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": false,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}