如何开发Eclipse插件扩展Obeo UML Designer,实现类文件信息展示?
Alright, let's break down exactly how to build an Eclipse plugin that extends Obeo UML Designer to load specific class files and visualize their properties, associations, and more in UML diagrams. I’ve tackled similar extensions before, so here’s a practical, step-by-step guide:
First things first—you’ll need the right tools to build this extension:
- Install Eclipse for RCP and RAP Developers (it includes all the RCP plugin tools required)
- Add Obeo UML Designer via the Eclipse Marketplace (search for "Obeo UML Designer") or its official update site
- Install core dependencies: EMF (Eclipse Modeling Framework) and UML2 SDK (you can find these in Eclipse’s "Install New Software" menu under the Eclipse Modeling Tools site)
Obeo UML Designer is built on top of Sirius, an open-source modeling framework. The key extension points we’ll leverage are:
org.eclipse.ui.commands/org.eclipse.ui.handlers: Add a user-triggerable action (like a right-click menu option) to select class files- Sirius session API: To sync your parsed UML model with Obeo’s diagram editor
- EMF resource APIs: To create and manage UML model elements from parsed class data
Let’s start building the plugin:
- Go to
File > New > Plug-in Projectand name it something likecom.yourcompany.umlclassloader - In the setup wizard, make sure to include dependencies on:
org.eclipse.uml2.uml(core UML model support)org.eclipse.sirius&org.eclipse.sirius.diagram(Obeo’s underlying framework)org.eclipse.ui(Eclipse UI integration)org.eclipse.jdt.core(if using Eclipse’s JDT to parse class files) ororg.objectweb.asm(a lighter alternative for bytecode parsing)
- Update your
MANIFEST.MFto declare all these required dependencies explicitly.
Next, we need to read class files and map their content to UML elements. Let’s use Eclipse JDT’s AST (Abstract Syntax Tree) for this example—it’s tightly integrated with Eclipse and handles .java files seamlessly:
- Create a handler class that implements
IHandler—this will run when the user triggers the load action. - Use JDT to extract class details (name, fields, associations) and convert them to UML objects:
// Initialize a new UML model resource ResourceSet resourceSet = new ResourceSetImpl(); Resource resource = resourceSet.createResource(URI.createURI("temp.uml")); Package umlPackage = UMLFactory.eINSTANCE.createPackage(); resource.getContents().add(umlPackage); // Get the selected class file from Eclipse's workspace IFile selectedFile = ...; // Retrieve from active selection IClassFile classFile = JavaCore.createClassFileFrom(selectedFile); IType javaClass = classFile.getType(); // Create a UML Class element org.eclipse.uml2.uml.Class umlClass = UMLFactory.eINSTANCE.createClass(); umlClass.setName(javaClass.getElementName()); umlPackage.getPackagedElements().add(umlClass); // Convert Java fields to UML Properties for (IField field : javaClass.getFields()) { Property umlProperty = UMLFactory.eINSTANCE.createProperty(); umlProperty.setName(field.getElementName()); // Resolve field type to UML Type (handle primitives and other classes) IType fieldType = field.getType(); String typeName = fieldType.getFullyQualifiedName(); Type umlType = umlPackage.getOwnedType(typeName); if (umlType == null) { // Create a placeholder class or DataType if type doesn't exist umlType = fieldType.isPrimitive() ? UMLFactory.eINSTANCE.createDataType() : UMLFactory.eINSTANCE.createClass(); umlType.setName(typeName); umlPackage.getPackagedElements().add(umlType); } umlProperty.setType(umlType); umlClass.getOwnedAttributes().add(umlProperty); // Create a UML Association if the field references another class if (umlType instanceof org.eclipse.uml2.uml.Class) { Association association = UMLFactory.eINSTANCE.createAssociation(); association.getOwnedEnds().add(umlProperty); Property oppositeEnd = UMLFactory.eINSTANCE.createProperty(); oppositeEnd.setName(umlClass.getName().toLowerCase() + "s"); oppositeEnd.setType(umlClass); oppositeEnd.setLower(0); oppositeEnd.setUpper(-1); // Set multiplicity to 0..* association.getOwnedEnds().add(oppositeEnd); ((org.eclipse.uml2.uml.Class)umlType).getOwnedAttributes().add(oppositeEnd); umlPackage.getPackagedElements().add(association); } }
Once you have your UML model, you need to render it in Obeo’s designer. Use Sirius’ API to create or update a diagram:
// Get the active Sirius session (Obeo's model-diagram sync context) Session session = SessionManager.INSTANCE.getActiveSession(); if (session != null) { // Enable Obeo's default Class Diagram viewpoint if it's not active Viewpoint classViewpoint = ViewpointRegistry.getInstance().getViewpoint("Design"); if (classViewpoint != null && !session.getSelectedViewpoints(false).contains(classViewpoint)) { SessionManager.INSTANCE.selectViewpoints(session, Collections.singleton(classViewpoint)); } // Create a new Class Diagram for your UML package DRepresentationDescriptor diagramDescriptor = SiriusServices.createRepresentation( umlPackage, classViewpoint, "Loaded Class Diagram", session ); // Open the diagram in Obeo's editor if (diagramDescriptor != null) { DRepresentation diagram = diagramDescriptor.getRepresentation(); PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor( new RepresentationEditorInput(diagram), "org.eclipse.sirius.diagram.ui.part.SiriusDiagramEditorID" ); } }
Let’s give users a way to trigger the load action. Add a right-click menu option for .java/.class files via your plugin’s plugin.xml:
<extension point="org.eclipse.ui.commands"> <command id="com.yourcompany.umlclassloader.loadClass" name="Load Class into UML Diagram"> </command> </extension> <extension point="org.eclipse.ui.handlers"> <handler class="com.yourcompany.umlclassloader.handlers.LoadClassHandler" commandId="com.yourcompany.umlclassloader.loadClass"> </handler> </extension> <extension point="org.eclipse.ui.menus"> <menuContribution locationURI="popup:org.eclipse.ui.popup.any?after=additions"> <command commandId="com.yourcompany.umlclassloader.loadClass" style="push"> <visibleWhen checkEnabled="false"> <with variable="activeMenuSelection"> <iterate ifEmpty="false"> <adapt type="org.eclipse.core.resources.IFile"> <test property="org.eclipse.core.resources.name" value="*.java"/> <test property="org.eclipse.core.resources.name" value="*.class"/> </adapt> </iterate> </with> </visibleWhen> </command> </menuContribution> </extension>
- Run a test Eclipse instance (
Run > Run As > Eclipse Application) - In the test environment, create an Obeo UML project, right-click a .java/.class file, and select "Load Class into UML Diagram"
- Verify that the class’s properties and associations appear correctly in the diagram
- If everything works, export your plugin as a deployable fragment (
File > Export > Deployable plug-ins and fragments)
- Type Resolution: Primitive types should map to UML DataTypes, not Classes. For external classes, create placeholder elements or resolve them from the workspace if possible.
- Session Management: Always work with the active Sirius session—this ensures your model stays synced with the diagram.
- Performance: Add progress indicators for large class files, as parsing and diagram rendering can take time.
- Error Handling: Add try-catch blocks to handle invalid class files, missing dependencies, or empty selections.
内容的提问来源于stack exchange,提问作者Horia

