Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Graphiti » Getting 'null' instead of the expected BO from a PE in a generated diagram
Getting 'null' instead of the expected BO from a PE in a generated diagram [message #1176305] Fri, 08 November 2013 03:50 Go to next message
Laurent Le Moux is currently offline Laurent Le Moux
Messages: 110
Registered: September 2011
Senior Member
Hi all,

Following the Graphiti tutorial, I created a ServiceEditor with an associated ServiceAddFeature. This works fine. I can create a diagram containing a picture element (PE) displaying my service business object (BO).
When I select the PE, my property view also successfully shows my service name.

Then, following recommendations found in this forum, I created a new Editor in order to display a generated diagram. This works fine except that if I now select my service PE, the property view doesn't display the name attribute of my service BO anymore...

In debug mode, it appears that AdapterFactory#getAdapter doesn't get the BO from the selected PE.

	public Object getAdapter(Object adaptableObject, Class adapterType) {
	    if (adaptableObject instanceof GraphitiShapeEditPart && adapterType == IPropertySource.class) {
	    	EObject element = (EObject)Graphiti.getLinkService()
					.getBusinessObjectForLinkedPictogramElement(((GraphitiShapeEditPart)adaptableObject).getPictogramElement());
...
	}


With my 'classical' editor, 'element' corresponds to my service BO after calling Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement.
Whereas, in the generated diagram editor context, the call returns null...

To create my PE element in the generated diagram, I reuse - with a slight change - the ServiceAddFeature which works fine for my 'classical' editor.

			ServiceAddFeature srvAddFeature =
					new ServiceAddFeature(new GeneratedDiagramTypeProvider().getFeatureProvider()) {
						@Override
						protected Diagram getDiagram() {
							return d;
						}
					};

...

			for (Service s : map.keySet()) {
				// Add service widget
				AddContext addCtx = new AddContext();
				addCtx.setNewObject(s);
				addCtx.setTargetContainer(d);
				PictogramElement srvpe = srvAddFeature.add(addCtx);
...


How comes the service 's' is not correctly linked to 'srvpe' anymore ?
Is there something wrong in the way I use my ServiceAddFeature or in the way I create a AddContext ?

Kind regards,

Laurent
Re: Getting 'null' instead of the expected BO from a PE in a generated diagram [message #1176938 is a reply to message #1176305] Fri, 08 November 2013 12:01 Go to previous messageGo to next message
Laurent Le Moux is currently offline Laurent Le Moux
Messages: 110
Registered: September 2011
Senior Member
Investigating a little bit further LinkServiceImpl.class, getBusinessObjectForLinkedPictogramElement calls getAllBusinessObjectsForLinkedPictogramElement which - in turn - calls getLinkForPictogramElement.

In this last method, pictogramElement.getLink() returns null which - of course - prevents from getting my associate BO... Sad

But in my ServiceAddFeature#add, following the tutorial, both the container and text shapes are linked to my service BO.

    public PictogramElement add(IAddContext context) {
    	IAddContext ctx = context;
    	Service addedService = (Service) context.getNewObject();
        Diagram targetDiagram = (Diagram) context.getTargetContainer();
 
        // CONTAINER SHAPE WITH ROUNDED RECTANGLE
        ContainerShape containerShape = Graphiti.getPeCreateService().createContainerShape(targetDiagram, true);
        
        // define a default size for the shape
	    IColorConstant ELEMENT_TEXT_FOREGROUND = IColorConstant.BLACK;
	    IColorConstant ELEMENT_FOREGROUND = IColorConstant.RED;
	    IColorConstant ELEMENT_BACKGROUND = IColorConstant.LIGHT_LIGHT_GRAY;

	    int width = 100;
        int height = 50;
        IGaService gaService = Graphiti.getGaService();
        IPeCreateService peCreateService = Graphiti.getPeCreateService();

        RoundedRectangle roundedRectangle; // need to access it later
 
        {
            // create and set graphics algorithm
            roundedRectangle =
                gaService.createRoundedRectangle(containerShape, 5, 5);
            roundedRectangle.setForeground(manageColor(ELEMENT_FOREGROUND));
            roundedRectangle.setBackground(manageColor(ELEMENT_BACKGROUND));
            roundedRectangle.setLineWidth(2);
            gaService.setLocationAndSize(roundedRectangle, ctx.getX(), ctx.getY(), width, height);
            
            // create link and wire it
            link(containerShape, addedService);
        }
 
        // SHAPE WITH LINE
        {
            // create shape for line
            Shape shape = peCreateService.createShape(containerShape, false);
 
            // create and set graphics algorithm
            Polyline polyline = gaService.createPolyline(shape, new int[] { 0, 20, width, 20 });
            polyline.setForeground(manageColor(ELEMENT_FOREGROUND));
            polyline.setLineWidth(2);
        }
 
        // SHAPE WITH TEXT
        {
            // create shape for text
            Shape shape = peCreateService.createShape(containerShape, false);
 
            // create and set text graphics algorithm
            Text text = gaService.createText(shape, addedService.getName());
            text.setForeground(manageColor(ELEMENT_TEXT_FOREGROUND));
            text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER );
            // vertical alignment has as default value "center"
            text.setFont(gaService.manageDefaultFont(getDiagram(), false, true));
            gaService.setLocationAndSize(text, 0, 0, width, 20);
 
            // create link and wire it
            link(shape, addedService);
        }
 
        // add a chopbox anchor to the shape
        peCreateService.createChopboxAnchor(containerShape);
        
        // call the layout feature
        layoutPictogramElement(containerShape);

        return containerShape;
    }


The ServiceAddFeature#add method seems to be ok as the name of my service is correctly displayed in the diagram itself.
So, I really wonder why the link seems to be 'lost' in the case of property view displaying a selection in this generated diagram.

Any idea ?
Re: Getting 'null' instead of the expected BO from a PE in a generated diagram [message #1177258 is a reply to message #1176938] Fri, 08 November 2013 16:56 Go to previous message
Laurent Le Moux is currently offline Laurent Le Moux
Messages: 110
Registered: September 2011
Senior Member
Ok, I found what the problem was.
During diagram generation, the editor is not open and as such, the diagram type provider has not been initialized with the diagram under construction...

So, when executing ServiceAddFeature#add in that context, link(containerShape, addedService) leads to an internal call in AbstractFeatureProvider#createPictogramLink to AbstractDiagramTypeProvider#getDiagram which returns null and the link is not created (see below).

	private PictogramLink createPictogramLink(PictogramElement pe) {
		PictogramLink ret = null;
		Diagram diagram = getDiagramTypeProvider().getDiagram();
		if (diagram != null) {
			// create new link
			ret = PictogramsFactory.eINSTANCE.createPictogramLink();
			ret.setPictogramElement(pe);

			// add new link to diagram
			diagram.getPictogramLinks().add(ret);
		}
		return ret;
	}


The solution is to reuse ServiceAddFeature with one more change to make sure the generated diagram will be available.

			ServiceAddFeature srvAddFeature =
					new ServiceAddFeature(new GeneratedDiagramTypeProvider() {
						@Override
						public Diagram getDiagram() {
							return d;
						}
					}.getFeatureProvider()) {
						@Override
						protected Diagram getDiagram() {
							return d;
						}
					};


Regards,

Laurent
Previous Topic:2 Diagrams 2 Liked objects
Next Topic:Load and Synchronize business objects across several resource files
Goto Forum:
  


Current Time: Thu Apr 17 05:53:26 EDT 2014

Powered by FUDForum. Page generated in 0.02809 seconds