Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Graphiti » programmatic connection creation
programmatic connection creation [message #782947] Tue, 24 January 2012 19:39 Go to next message
Josef Pohl is currently offline Josef PohlFriend
Messages: 82
Registered: January 2012
Member
Hi all,
I think this topic has been covered in some way or another a few times but I have not quite grasped the context of the solutions.

I am trying to create the links represented in my model. I can add nodes, from the model, to the canvas. I also have connections in the model, which are associated with specific nodes. The following code, from my model load handler, obviously does not work. I believe I have to set the anchor points.

		for(Iterator<Link> liter = links.iterator(); liter.hasNext();){
			Link inst = liter.next();

			AddContext addC = new AddContext();
			addC.setNewObject(inst);
			addC.setTargetContainer(diagram);
			
			IAddFeature addFeature = featureProvider.getAddFeature(addC);
			if(addFeature.canAdd(addC)){
				addFeature.add(addC);
			}
		}


I can get the node elements (source and target) associated with a specific connection in the model. I create the node features (addFeature) in a similar iteration through an EList. In my addFeature (add) for nodes I create a ChopBoxAnchor for each node.

How can I, having only the model node, retrieve the pictogram element associated with that node (linked to that node)?

What is the process to retrieve an Anchor from the pictogram element associated with the node?

Thanks again
Joe
Re: programmatic connection creation [message #783254 is a reply to message #782947] Wed, 25 January 2012 11:05 Go to previous messageGo to next message
Michael Wenz is currently offline Michael WenzFriend
Messages: 1640
Registered: July 2009
Location: Walldorf, Germany
Senior Member
The creation of connections is done by ICreateConnectionFeature instances,
which are retrieved by the method getCreateConnectionFeatures in the feature
provider. What you are doning is only applicable to shapes not to
connetions.

Michael
Re: programmatic connection creation [message #783388 is a reply to message #783254] Wed, 25 January 2012 16:22 Go to previous messageGo to next message
Josef Pohl is currently offline Josef PohlFriend
Messages: 82
Registered: January 2012
Member
Hi Michael,

Thanks for your reply. I guess I am a bit confused though. Do you happen to know of any existing examples where this is done?

I guess here is how I thought the flow should go:

iterate over links (Business Objects)
-- Get Source and Target Nodes (Business Objects)
-- Get GA for Source and Target (not sure how???)
-- Get Anchors from GA for Source and Target
-- Make AddConnectionContext with link (BO) and anchors

-- I believe here is where the ICreateConnectionFeature stuff comes in and I can
call canCreate and create from here.

Am I missing something from this scenario? Is there any good way to get the GA from source and target nodes (having only, directly, the business objects.)

Thanks!
Joe
Re: programmatic connection creation [message #783901 is a reply to message #783388] Thu, 26 January 2012 17:36 Go to previous messageGo to next message
Josef Pohl is currently offline Josef PohlFriend
Messages: 82
Registered: January 2012
Member
Hi all,
I thought I might try to clarify my issue here as I have not made much headway on it.

As I noted above I am trying to load an EMF file into a diagram, creating all of the nodes and links between those nodes.

When creating a node, a priori, I do not have any information about whether or not a node has a link coming to or from it, or both. However I can add all of the nodes to the diagram, using my addFeature routine, and have them displayed in a reasonable fashion.

I do this creation in a handler called from a project explorer context menu option.

It is only when I get to the link that I have the information about what nodes are connected. Now, it appears that I need to be able to access the specific graphics algorithm linked to the business object I created in the previous step.

The question becomes, how do I locate the specific GA?
In scope I have the diagram, and two Resource Sets. One for my business objects and one for the diagram. I also have the business objects loaded from the file.

Any thoughts on how I can use any of these components to retrieve the GA and hence the anchors?

Thanks in advance,
Joe
Re: programmatic connection creation [message #784001 is a reply to message #783901] Thu, 26 January 2012 22:55 Go to previous messageGo to next message
Josef Pohl is currently offline Josef PohlFriend
Messages: 82
Registered: January 2012
Member
Hi all,
Well, I made a bit of progress going back to what Michael originally suggested. (Sorry, it took me a bit to figure out exactly what you meant and connect it with what was going on.) I can now get links displayed on the canvas going to and from the appropriate nodes. Cool!

I have now run into two additional aberrations though. (I know you are thinking... "of course he has...")

1. The link pictogram is a dotted red line with a black arrow head as opposed to a solid black line with an arrow head. How can I get this to go back to just being a black line?

2. When I create the links I iterate over a EList containing Link type elements. This list is generated from the model file top level element. When I iterate over the list and create new links, these new links get added back into the original list.
This causes a run time error. I can avoid this problem by using just a for loop with a counter (see below, iterator code is commented out). So basically, it appears that it is trying to add duplicate links to my model. Is there anything that I am doing in my code that would cause this to occur? I posted the, rather messy, doExecute function in it's entirety. Sorry about that but there may be something pertinent in an odd spot.

I additionally added my code for the connection creation. Which might be the source of the duplicates. Should I possibly create a different Create<myConnection>Feature class to handle these separate use cases (manual generation and auto-generated from model file)?

Thanks again,
Joe



	protected void doExecute() {
		Diagram diagram = Graphiti.getPeCreateService().createDiagram("egsndiagram", baseName, true);
		IFolder diagramFolder = project.getFolder("src/diagrams/");
		System.out.println("BASENAME: " + baseName);
	//FILE SETUP STUFF	
		//DIAGRAM
		IFile diagramFile = diagramFolder.getFile(diagramName + ".diagram");
		
		URI uri = URI.createPlatformResourceURI(diagramFile.getFullPath().toString(), true);

		createdResource = editingDomain.getResourceSet().createResource(uri);
		createdResource.getContents().add(diagram);
		
		//MODEL
		IFile modelFile = diagramFolder.getFile(modelName + ".egsn");
		URI fileURI = URI.createFileURI(modelFile.getFullPath().toString());
		
		ResourceSet resourceSet = new ResourceSetImpl();
		createdModelResource = resourceSet.getResource(fileURI, true);
		
		Set<EObject> eobjects = new HashSet<EObject>();
		eobjects.addAll(createdModelResource.getContents());
		
		SafetyCase sc = null;
		PictogramLink link = PictogramsFactory.eINSTANCE.createPictogramLink();
		diagram.setLink(link);
	//FINDING TOP LEVEL OBJECT FROM RESOURCESET
		for(Iterator<EObject> iterator = eobjects.iterator(); iterator.hasNext();)
		{
			EObject node = iterator.next();
			if(node instanceof SafetyCase){
				sc = (SafetyCase) node;	
			}
		}
		
		if(sc == null){
			sc = XxegsnFactory.eINSTANCE.createSafetyCase();
			System.out.println("SAFETYCASE is NULL");
		}
		
		link.getBusinessObjects().add(sc);
	// Get nodes and links from safety case argument
		EList<Node> nodes = sc.getNode();
		EList<Link> links = sc.getLink();
		
		IDiagramTypeProvider dtp = GraphitiUi.getExtensionManager().createDiagramTypeProvider(diagram,
				"diagram.EgsndiagramTypeProvider"); 
		
		IFeatureProvider featureProvider = dtp.getFeatureProvider();
		createdResource.setTrackingModification(true);
		createdModelResource.setTrackingModification(true);

		try{
			createdResource.save(Collections.EMPTY_MAP);
			createdModelResource.save(Collections.EMPTY_MAP);
		}catch(IOException e) {}
		
		int x = 20;
		int y = 20;
// Adding nodes 
		for(Iterator<Node> iter = nodes.iterator(); iter.hasNext();){
			Node inst = iter.next();
			
			AddContext addC = new AddContext();
			addC.setNewObject(inst);
			addC.setTargetContainer(diagram);
			addC.setLocation(x, y);
			x+= 20;
			y+=20;
		
			IAddFeature addFeature = featureProvider.getAddFeature(addC);
			if (addFeature.canAdd(addC)) {
				addFeature.add(addC);
			}
			
			//addC.getTargetContainer().g
			
		}
	//ADDING LINKS	
		EList<PictogramLink> plinks = diagram.getPictogramLinks();

		int size = links.size();
	//	for(Iterator<Link> liter = links.iterator(); liter.hasNext();){
	//		Link inst = liter.next();
	    for(int i = 0; i < size ; i++){
	    	Link inst = links.get(i);
		    if(inst instanceof Link){
				System.out.println("LINK instance");
			}
			Node src = inst.getFrom();
			Node trgt = inst.getTo();
			
			Anchor srcAnchor = getAnchorFromPE(plinks, src);
			Anchor trgAnchor = getAnchorFromPE(plinks, trgt);
			
			
			ICreateConnectionFeature[] createCFeatureList = featureProvider.getCreateConnectionFeatures();
			ICreateConnectionFeature createCFeature = null;
			// is there a better way to do this???
			if(inst instanceof IsSolvedBy){
				createCFeature = createCFeatureList[0];
			}
			else {
				createCFeature = createCFeatureList[1];
			}
			
			if(srcAnchor != null && trgAnchor != null){
				CreateConnectionContext createCont = new CreateConnectionContext();
				createCont.setSourcePictogramElement(srcAnchor.getParent());
				createCont.setSourceAnchor(srcAnchor);
				createCont.setTargetPictogramElement(trgAnchor.getParent());
				createCont.setTargetAnchor(trgAnchor);
				if(createCFeature.canCreate(createCont)){
					createCFeature.create(createCont);
				}
			}
		
		}



    public Connection create(ICreateConnectionContext context) {
        Connection newConnection = null;
 
        // get Nodes which should be connected
        // These can be restricted to the appropriate types of nodes here.
        Node source =  getNode(context.getSourceAnchor());
        Node target =  getNode(context.getTargetAnchor());
 
        if (source != null && target != null) {
            // create new business object
        	IsSolvedBy isb = XxegsnFactory.eINSTANCE.createIsSolvedBy();
        	isb.setIdentifier("Is Solved By");
        	isb.setFrom(source);
        	isb.setTo(target);
     
            SafetyCase sc = (SafetyCase) getDiagram().getLink().getBusinessObjects().get(0);
            sc.getLink().add(isb);


        	AddConnectionContext addContext = new AddConnectionContext(context.getSourceAnchor(), context.getTargetAnchor());

     
        	addContext.setNewObject(isb);

            newConnection = (Connection) getFeatureProvider().addIfPossible(addContext);
            if(newConnection == null){
            	System.out.println("NULL connection");
            }

        }
       
        return newConnection;
    }

[Updated on: Thu, 26 January 2012 23:23]

Report message to a moderator

Re: programmatic connection creation [message #896890 is a reply to message #784001] Fri, 20 July 2012 10:22 Go to previous messageGo to next message
Surya Kathayat is currently offline Surya KathayatFriend
Messages: 44
Registered: July 2012
Member
Hi Joe,

I am also trying to draw connections programatically (only able to draw nodes in the editor so far).

How do you get Anchors in the method "getAnchorFromPE" used in the following lines in your code.?


Anchor srcAnchor = getAnchorFromPE(plinks, src);
Anchor trgAnchor = getAnchorFromPE(plinks, trgt);

Thanks in advance.
Surya

[Updated on: Fri, 20 July 2012 10:41]

Report message to a moderator

Re: programmatic connection creation [message #896950 is a reply to message #896890] Fri, 20 July 2012 13:53 Go to previous messageGo to next message
Surya Kathayat is currently offline Surya KathayatFriend
Messages: 44
Registered: July 2012
Member
No Message Body

[Updated on: Fri, 20 July 2012 13:54]

Report message to a moderator

Re: programmatic connection creation [message #896972 is a reply to message #896950] Fri, 20 July 2012 15:34 Go to previous messageGo to next message
Aljoscha Hark is currently offline Aljoscha HarkFriend
Messages: 24
Registered: March 2012
Junior Member
i try to answer josef pauls questions:

to 1.: this normally indicates that the connection is "out of date" - the updatefeature for it says "needs update". when you select such connection and press ctrl+f5 it tries to process the update. normally this is not necessary on the creation/addition of PE/GA elements. when the update does not change it to "solid black", something is wrong in the add/layout/update features for that connection. possible solution: see answer for 2.

to 2.: there is an error in the "initialize diagram command" i think. if i understand you correctly, you want to initialize a diagram from a existing and "consistent" model. then you must not use create features, because they are typically used to CREATE model artifacts. use only ADD features.

in the following i attach the main part of the addition for an EPackage (that means EClass and EReference would be added. hint: getElement() returns the EPackage, for which to add the diagram information.

int x = 0;
int y = 0;

// store the diagram elements for the added PEs in here
Map<EClass, ContainerShape> classifiers = new LinkedHashMap<EClass, ContainerShape>();
for (EClassifier c : getElement().getEClassifiers()) {
 // create the context information
 AddContext context = new AddContext();
 context.setNewObject(c);
 context.setTargetContainer(pe);
 context.setX(50 + x * 200);
 context.setY(50 + y * 200);

 IAddFeature feature = fp.getAddFeature(context);
 if (feature.canAdd(context)) {
  // add it
  PictogramElement cpe = feature.add(context);

  // store it for references and inheritances
  if (c instanceof EClass && cpe instanceof ContainerShape) {
   classifiers.put((EClass) c, (ContainerShape) cpe);
  }

  // move forward
  x++;
  if (x > 5) {
   y++;
   x = 0;
  }
 }
}

// add all references to diagram
for (EClassifier c : getElement().getEClassifiers()) {
 if (c instanceof EClass) {
  // get source shape
  ContainerShape source = classifiers.get(c);
  if (source == null) {
   Activator.get().error("No pictogram element found for source.");
   continue;
  }

  // references
  for (EStructuralFeature sf : ((EClass) c).getEStructuralFeatures()) {
   if (sf instanceof EReference) {
    // get target shape
    ContainerShape target = classifiers.get(((EReference) sf).getEReferenceType());
    if (target == null) {
     Activator.get().error("No pictogram element found for target.");
     continue;
    }

    // get source anchor
    Anchor sourceAnchor = Graphiti.getPeService().getChopboxAnchor(source);
    if (sourceAnchor == null) {
     Activator.get().error("No anchor found for source pictogram element.");
     continue;
    }

    // get target anchor
    Anchor targetAnchor = Graphiti.getPeService().getChopboxAnchor(target);
    if (targetAnchor == null) {
     Activator.get().error("No anchor found for target pictogram element.");
     continue;
    }

    // add it
    AddConnectionContext context = new AddConnectionContext(sourceAnchor, targetAnchor);
    context.setNewObject(sf);

    IAddFeature feature = fp.getAddFeature(context);
    if (feature.canAdd(context)) {
     feature.add(context);
    }
   }
  }


Activator is used to log messages in here.

i hope this could help.

greets,
aljoscha
Re: programmatic connection creation [message #896973 is a reply to message #896972] Fri, 20 July 2012 15:38 Go to previous message
Aljoscha Hark is currently offline Aljoscha HarkFriend
Messages: 24
Registered: March 2012
Junior Member
@Surya Kathayat: in the middle of the code snippet you can see how to get a chopbox anchor from a PE. when you use other anchors, you could create your own getter method, as seen in
Graphiti.getPeService().getChopboxAnchor(AnchorContainer)
.
Previous Topic:Store a map in the properties of a pictogramelement
Next Topic:creating new editor
Goto Forum:
  


Current Time: Mon Dec 22 02:49:34 GMT 2014

Powered by FUDForum. Page generated in 0.01811 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software