/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.diagram.ui.pakkage; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.draw2d.geometry.Point; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.notification.util.DefaultIgnorableNotificationSource; import org.teiid.designer.core.notification.util.NotificationUtilities; import org.teiid.designer.core.resource.EmfResource; import org.teiid.designer.core.transaction.SourcedNotification; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.diagram.ui.DiagramUiConstants; import org.teiid.designer.diagram.ui.DiagramUiPlugin; import org.teiid.designer.diagram.ui.PluginConstants; import org.teiid.designer.diagram.ui.connection.NodeConnectionModel; import org.teiid.designer.diagram.ui.editor.DiagramEditorUtil; import org.teiid.designer.diagram.ui.model.DiagramModelFactoryImpl; import org.teiid.designer.diagram.ui.model.DiagramModelNode; import org.teiid.designer.diagram.ui.model.LabelModelNode; import org.teiid.designer.diagram.ui.notation.NotationModelGenerator; import org.teiid.designer.diagram.ui.notation.uml.model.UmlClassifierNode; import org.teiid.designer.diagram.ui.util.DiagramEntityManager; import org.teiid.designer.diagram.ui.util.DiagramUiUtilities; import org.teiid.designer.jdbc.JdbcSource; import org.teiid.designer.metamodels.core.ModelAnnotation; import org.teiid.designer.metamodels.diagram.Diagram; import org.teiid.designer.metamodels.diagram.DiagramLinkType; import org.teiid.designer.ui.viewsupport.ModelUtilities; /** * PackageDiagramModelFactory * * @since 8.0 */ public class PackageDiagramModelFactory extends DiagramModelFactoryImpl implements DiagramUiConstants { private String sNotationId; private static final int I_BORDER = 20; private static final int X_INC = 20; private static final int Y_INC = 10; private static final int X_MAX = 600; private static Point startingPoint = new Point(I_BORDER, I_BORDER); private static int yInc = 20; private static final String KEY_PACKAGE_DIAGRAM_NAME = "DiagramNames.packageDiagram"; //$NON-NLS-1$ private static final String THIS_CLASS = "PackageDiagramModelFactory"; //$NON-NLS-1$ private NotationModelGenerator generator; private HashMap reconcileClassifierNodes; /** * */ public PackageDiagramModelFactory() { } /** * Create a DiagramModelNode. */ public DiagramModelNode createModel( Object baseObject ) { return null; } /** * Create a DiagramModelNode. */ @Override public DiagramModelNode createModel( Object baseObject, String sNotationId, IProgressMonitor monitor ) { // Return null if the baseObject is not a org.teiid.designer.metamodels.diagram.Diagram if (!(baseObject instanceof Diagram)) { return null; } HashMap nodeMap = new HashMap(); setSNotationId(sNotationId); Diagram diagram = (Diagram)baseObject; DiagramModelNode diagramModelNode = null; List contents = null; // Get package EObject from PackageDiagramResource EObject packageObject = null; Object targetObject = diagram.getTarget(); // Get contents of the package, iterate EObjects if (targetObject != null && targetObject instanceof EObject && !(targetObject instanceof ModelAnnotation)) { packageObject = diagram.getTarget(); // diagramModelNode = new PackageDiagramNode(packageObject, Util.getString( KEY_PACKAGE_DIAGRAM_NAME) ); diagramModelNode = new PackageDiagramNode(diagram, Util.getString(KEY_PACKAGE_DIAGRAM_NAME)); contents = packageObject.eContents(); } else if (targetObject != null && targetObject instanceof EObject && targetObject instanceof ModelAnnotation) { diagramModelNode = new PackageDiagramNode(diagram, Util.getString(KEY_PACKAGE_DIAGRAM_NAME)); ModelResource modelResource = ModelUtilities.getModelResourceForModelObject(diagram); if (modelResource != null) { try { contents = modelResource.getEObjects(); } catch (ModelWorkspaceException e) { contents = Collections.EMPTY_LIST; String message = Util.getString("ModelErrors.getContentError", modelResource.getItemName()); //$NON-NLS-1$ DiagramUiConstants.Util.log(IStatus.ERROR, e, message); } } else { contents = Collections.EMPTY_LIST; } } else { contents = Collections.EMPTY_LIST; } int interval; int iStage; int iCount; int nComponents = contents.size(); String progressMessage; int nStages = 1; if (nComponents < 10) interval = 1; else if (nComponents < 50) interval = 2; else if (nComponents < 200) interval = 5; else if (nComponents < 400) interval = 10; else if (nComponents < 800) interval = 20; else interval = (int)((double)nComponents / (double)50); nStages = (int)((double)nComponents / (double)interval); int progressInc = (int)(50.0 / nStages); if (progressInc == 0) progressInc = 1; boolean showProgress = false; if (monitor != null) { monitor.subTask("Creating Model Components"); //$NON-NLS-1$ showProgress = true; } if (!contents.isEmpty()) { iStage = 1; iCount = 0; int nComps = 0; Iterator iter = contents.iterator(); // long startTime = 0; if (getGenerator() != null) { while (iter.hasNext()) { // Get current EObject EObject eObj = (EObject)iter.next(); // Check to see that it isn't a non-drawable object like "JdbcSource" (i.e. connection) object. if (isDrawable(eObj)) { // startTime = System.currentTimeMillis(); DiagramModelNode childModelNode = getGenerator().createModel(eObj, diagram); // if( nComps % 50 == 0 ) // System.out.println(" PDMF.createModel() Object[" + nComps + "] DeltaT = [" + // (System.currentTimeMillis() - startTime) + "]"); if (childModelNode != null) { nodeMap.put(eObj, childModelNode); childModelNode.setParent(diagramModelNode); diagramModelNode.addChild(childModelNode); if (showProgress) { nComps++; iCount++; if (iCount == interval && iStage < nStages) { progressMessage = "Created " + nComps + //$NON-NLS-1$ " of " + nComponents + //$NON-NLS-1$ " Diagram Components"; //$NON-NLS-1$ monitor.subTask(progressMessage); monitor.worked(progressInc); iStage++; iCount = 0; } } } } } } else { Util.log(IStatus.WARNING, Util.getString(Errors.MODEL_GENERATOR_FAILURE)); } if (showProgress) { monitor.subTask("Adding Association Links"); //$NON-NLS-1$ } if (!diagramModelNode.getChildren().isEmpty()) { // Let's create a map containing binary associations keyed to the EObject reference HashMap connMap = new HashMap(); nComps = 0; // Let's get contents, and get associations for each object List realAssociations = new ArrayList(); List currentChildren = diagramModelNode.getChildren(); iter = currentChildren.iterator(); while (iter.hasNext()) { DiagramModelNode childModelNode = (DiagramModelNode)iter.next(); List childAssList = childModelNode.getAssociations(nodeMap); if (showProgress) { nComps++; if (nComps % 20 == 0) { progressMessage = "Constructed Associations for " + nComps + //$NON-NLS-1$ " of " + nComponents + //$NON-NLS-1$ " Diagram Components"; //$NON-NLS-1$ monitor.subTask(progressMessage); } } NodeConnectionModel nextConnection = null; NodeConnectionModel nextRealConnection = null; Iterator innerIter = null; Iterator subIter = childAssList.iterator(); while (subIter.hasNext()) { boolean connExists = false; nextConnection = (NodeConnectionModel)subIter.next(); // Check the map first if the reference object != null if (nextConnection.getModelObject() != null) { Object existingConn = connMap.get(nextConnection.getModelObject()); if (existingConn != null) connExists = true; } else { // no reference object, so we have to walk through all connections and check .equals() innerIter = realAssociations.iterator(); while (innerIter.hasNext() && !connExists) { nextRealConnection = (NodeConnectionModel)innerIter.next(); if (nextRealConnection != null && nextRealConnection.equals(nextConnection)) connExists = true; } } // if the connection still doesn't exist, then add to list and to map. if (!connExists) { if (nextConnection.getModelObject() != null) { connMap.put(nextConnection.getModelObject(), nextConnection); } realAssociations.add(nextConnection); } } // realAssociations.addAll(childModelNode.getAssociations()); } // List realAssociations = getGenerator().getAssociations(allAssociations, currentChildren); if (showProgress) monitor.subTask("Adding Association Labels"); //$NON-NLS-1$ iter = realAssociations.iterator(); String currentRouterStyle = DiagramLinkType.get(DiagramEditorUtil.getCurrentDiagramRouterStyle()).getName(); while (iter.hasNext()) { NodeConnectionModel nextAssociation = (NodeConnectionModel)iter.next(); if (nextAssociation.getDiagramLink() == null) nextAssociation.setRouterStyle(currentRouterStyle); ((DiagramModelNode)nextAssociation.getSourceNode()).addSourceConnection(nextAssociation); ((DiagramModelNode)nextAssociation.getTargetNode()).addTargetConnection(nextAssociation); List labelNodes = nextAssociation.getLabelNodes(); if (labelNodes != null && !labelNodes.isEmpty()) { Iterator labelIter = labelNodes.iterator(); LabelModelNode nextNode = null; while (labelIter.hasNext()) { nextNode = (LabelModelNode)labelIter.next(); diagramModelNode.addChild(nextNode); } } } } } return diagramModelNode; } protected NotationModelGenerator getGenerator() { if (generator == null) generator = DiagramUiPlugin.getDiagramNotationManager().getDiagramModelGenerator(getSNotationId()); return generator; } private boolean isValidDiagram( DiagramModelNode diagramModelNode ) { boolean result = false; Diagram diagram = (Diagram)diagramModelNode.getModelObject(); if (diagram != null && diagram.getTarget() != null) { ModelResource mr = ModelUtilities.getModelResourceForModelObject(diagram); if (mr != null) { String type = diagram.getType(); if (type != null) { if (type.equals(PluginConstants.PACKAGE_DIAGRAM_TYPE_ID)) result = true; } } } return result; } /* (non-Javadoc) * @See org.teiid.designer.diagram.ui.model.DiagramModelFactory#notifyModel(org.eclipse.emf.common.notify.Notification) */ @Override public boolean notifyModel( Notification notification, DiagramModelNode diagramModelNode, String sDiagramTypeId ) { boolean currentDiagramOK = true; Diagram diagram = (Diagram)diagramModelNode.getModelObject(); if (currentDiagramRemoved(diagram)) currentDiagramOK = false; if (currentDiagramOK && isValidDiagram(diagramModelNode) && sourceIsNotThis(notification) && shouldHandleNotification(notification, diagramModelNode)) { boolean requiredStart = false; boolean succeeded = false; boolean handleConstruction = !DiagramEditorUtil.isDiagramUnderConstruction(diagram); try { if (handleConstruction) { DiagramEditorUtil.setDiagramUnderConstruction(diagram); } // ------------------------------------------------- // Let's wrap this in a transaction!!! that way all constructed objects and layout properties // will result in only one transaction? // ------------------------------------------------- // Defect 23268 - changing isUndoable to false. DiagramEntities can be created and will be deleted as needed requiredStart = ModelerCore.startTxn(false, false, "Update Package Diagram", this); //$NON-NLS-1$$ handleNotification(notification, diagramModelNode); // We've cached up classifier nodes to reconcile so we only do it once... reconcileClassifiers(diagramModelNode); DiagramEntityManager.cleanDiagramEntities(diagram); succeeded = true; } catch (Exception ex) { DiagramUiConstants.Util.log(IStatus.ERROR, ex, ex.getClass().getName() + ":" + THIS_CLASS + ".notifyModel()"); //$NON-NLS-1$ //$NON-NLS-2$ } finally { if (requiredStart) { if (succeeded) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } if (handleConstruction) { DiagramEditorUtil.setDiagramConstructionComplete(diagram, true); } } } return currentDiagramOK; } private boolean shouldHandleNotification( Notification notification, DiagramModelNode diagramModelNode ) { boolean shouldHandle = false; Diagram currentDiagram = (Diagram)diagramModelNode.getModelObject(); Resource diagramModelResource = null; if (currentDiagram.getTarget() instanceof ModelAnnotation) { diagramModelResource = currentDiagram.getTarget().eResource(); } ModelResource diagramMR = ModelUtilities.getModelResourceForModelObject(currentDiagram); if (diagramMR != null) { if (notification instanceof SourcedNotification) { Object source = ((SourcedNotification)notification).getSource(); if (source == null || !source.equals(this)) { Collection notifications = ((SourcedNotification)notification).getNotifications(); if( !notifications.isEmpty() ) { Iterator iter = notifications.iterator(); Notification nextNotification = null; while (iter.hasNext() && !shouldHandle) { nextNotification = (Notification)iter.next(); Object targetObject = ModelerCore.getModelEditor().getChangedObject(nextNotification); if (targetObject != null) { if (targetObject instanceof EObject && !DiagramUiUtilities.isNonDrawingDiagramObject((EObject)targetObject)) { // If notification is from another "model resource" we don't care for Coarse // Mapping diagram. All objects are in same model. // Check here if the targetObject and document have the same resource, then set to TRUE; ModelResource mr = ModelUtilities.getModelResourceForModelObject((EObject)targetObject); if (mr != null && mr.equals(diagramMR)) { shouldHandle = true; } } else if (targetObject instanceof Resource && diagramModelResource != null) { Resource targetResource = (Resource)targetObject; if (targetResource.equals(diagramModelResource)) shouldHandle = true; } else if (targetObject instanceof Diagram && NotificationUtilities.isRemoved(nextNotification)) { ModelResource mr = ModelUtilities.getModelResourceForModelObject((EObject)targetObject); if (mr != null && mr.equals(diagramMR)) { shouldHandle = true; } } else if (targetObject instanceof Diagram) { if (notification.getNewValue() instanceof DiagramLinkType) shouldHandle = true; } } } } else { // Single SourceNotificationImpl Object changedObj = ModelerCore.getModelEditor().getChangedObject(notification); if( changedObj != null && changedObj instanceof EmfResource) { ModelResource mr = ModelUtilities.getModelResource((Resource)changedObj, false); if( mr == diagramMR) { shouldHandle = true; } } } } } else { // SINGLE NOTIFICATION Object targetObject = ModelerCore.getModelEditor().getChangedObject(notification); if (targetObject != null) { if (targetObject instanceof EObject && !DiagramUiUtilities.isNonDrawingDiagramObject((EObject)targetObject)) { // If notification is from another "model resource" we don't care for Coarse // Mapping diagram. All objects are in same model. // Check here if the targetObject and document have the same resource, then set to TRUE; ModelResource mr = ModelUtilities.getModelResourceForModelObject((EObject)targetObject); if (mr != null && mr.equals(diagramMR)) { shouldHandle = true; } } else if (targetObject instanceof Resource && diagramModelResource != null) { Resource targetResource = (Resource)targetObject; if (targetResource.equals(diagramModelResource)) shouldHandle = true; } else if (targetObject instanceof Diagram && NotificationUtilities.isRemoved(notification)) { ModelResource mr = ModelUtilities.getModelResourceForModelObject((EObject)targetObject); if (mr != null && mr.equals(diagramMR)) { shouldHandle = true; } } } } } return shouldHandle; } private boolean sourceIsNotThis( Notification notification ) { if (notification instanceof SourcedNotification) { Object source = ((SourcedNotification)notification).getSource(); if (source == null) return true; return !(source.equals(this)); } return true; } public Diagram getDiagram( EObject someTarget ) { ModelResource modelResource = ModelUtilities.getModelResourceForModelObject(someTarget); try { List returnedDiagrams = modelResource.getModelDiagrams().getDiagrams(someTarget); if (returnedDiagrams.size() == 1) { return (Diagram)returnedDiagrams.get(0); } // Find the one for package diagram Iterator iter = returnedDiagrams.iterator(); while (iter.hasNext()) { Diagram nextDiagram = (Diagram)iter.next(); if (nextDiagram.getType() != null && nextDiagram.getType().equals(PluginConstants.PACKAGE_DIAGRAM_TYPE_ID)) return nextDiagram; } } catch (CoreException e) { e.printStackTrace(); } return null; } /* (non-Javadoc) * @See org.teiid.designer.diagram.ui.model.ModelNotificationHandler#performUpdate(org.eclipse.emf.common.notify.Notification, int) */ public void handleNotification( Notification notification, DiagramModelNode packageDiagramModelNode ) { if (notification instanceof SourcedNotification) { Collection notifications = ((SourcedNotification)notification).getNotifications(); if( !notifications.isEmpty() ) { Iterator iter = notifications.iterator(); while (iter.hasNext()) { handleSingleNotification((Notification)iter.next(), packageDiagramModelNode); } } else { handleSingleNotification(notification, packageDiagramModelNode); } } else { handleSingleNotification(notification, packageDiagramModelNode); } } private void handleSingleNotification( Notification notification, DiagramModelNode packageDiagramModelNode ) { if (NotificationUtilities.isAdded(notification)) { performAdd(notification, packageDiagramModelNode); } else if (NotificationUtilities.isRemoved(notification)) { performRemove(notification, packageDiagramModelNode); } else if (NotificationUtilities.isChanged(notification)) { performChange(notification, packageDiagramModelNode); } } private void performAdd( Notification notification, DiagramModelNode packageDiagramModelNode ) { boolean performedChange = false; if (NotificationUtilities.isEObjectNotifier(notification)) { // we know that the object is not a child of a model resource !!!!! EObject targetObject = NotificationUtilities.getEObject(notification); // We know that we have an object that is not a child of a model resource, therefore, // it is safe to assume that it would exist on a normal package diagram. // Let's check to see if the target of the current "Diagram", is the same as the // parent of the new target object. Diagram diagram = (Diagram)packageDiagramModelNode.getModelObject(); boolean hasAssociations = false; EObject diagramTargetEObject = diagram.getTarget(); if (diagramTargetEObject.equals(targetObject)) { // We have a match, get the added children and hand them off to the generator to construct // and add to this packageDiagramModelNode DiagramModelNode childModelNode = null; EObject[] newChildren = NotificationUtilities.getAddedChildren(notification); for (int iChild = 0; iChild < newChildren.length; iChild++) { childModelNode = getModelNode(packageDiagramModelNode, newChildren[iChild]); if (childModelNode == null) { childModelNode = getGenerator().createModel(newChildren[iChild], (Diagram)packageDiagramModelNode.getModelObject()); if (childModelNode != null) { childModelNode.setParent(packageDiagramModelNode); childModelNode.setPosition(getStartingPoint()); packageDiagramModelNode.addChild(childModelNode); performedChange = true; if (!hasAssociations && childModelNode.getAssociations(getNodeMap(packageDiagramModelNode)) != null) { hasAssociations = true; } } } } if (performedChange && hasAssociations) updateAssociations(packageDiagramModelNode, packageDiagramModelNode); } else if (NotificationUtilities.addedChildrenParentIsNotifier(notification)) { boolean isNested = false; // Now we check to see if the target object is already in diagram DiagramModelNode targetNode = getNodeInDiagram(packageDiagramModelNode, targetObject); // if still null, check if it's nested if (targetNode == null) { targetNode = getModelNode(packageDiagramModelNode, targetObject); if (targetNode != null) isNested = true; } if (targetNode != null) { // This case where the node is in package diagram and we need to delegate to the object node to add a child // We have a match, get the added children and hand them off to the generator to construct // and add to this the corresponding targetNode EObject[] newChildren = NotificationUtilities.getAddedChildren(notification); if (newChildren.length > 0) { EObject childParent = newChildren[0].eContainer(); DiagramModelNode parentNode = getModelNode(packageDiagramModelNode, childParent); if (parentNode != null) { if (parentNode instanceof UmlClassifierNode) { addReconcileClassifier(parentNode); // ((UmlClassifierNode)parentNode).reconcile(); // ((UmlClassifierNode)parentNode).update(DiagramUiConstants.DiagramNodeProperties.CHILDREN); // performedChange = true; } else { for (int iChild = 0; iChild < newChildren.length; iChild++) { DiagramModelNode newNode = getGenerator().createChildModel(parentNode, newChildren[iChild]); if (newNode != null) performedChange = true; } } } if (performedChange) updateAssociations(parentNode, packageDiagramModelNode); } } if (isNested) { EObject parentEObject = targetObject.eContainer(); DiagramModelNode parentNode = getModelNode(packageDiagramModelNode, parentEObject); if (parentNode != null) { parentNode.updateForChild(false); } } } else { updateAssociations(packageDiagramModelNode, packageDiagramModelNode); } } else { Diagram diagram = (Diagram)packageDiagramModelNode.getModelObject(); EObject diagramTargetEObject = diagram.getTarget(); Resource diagramModelResource = null; boolean hasAssociations = false; if (diagramTargetEObject instanceof ModelAnnotation) diagramModelResource = diagramTargetEObject.eResource(); // target of notification (notifier) is ModelResource Object changedObj = ModelerCore.getModelEditor().getChangedObject(notification); if (diagramModelResource != null && changedObj != null && changedObj instanceof Resource) { Resource targetResource = (Resource)changedObj; if (targetResource.equals(diagramModelResource)) { // We have a match, get the added children and hand them off to the generator to construct // and add to this packageDiagramModelNode DiagramModelNode childModelNode = null; EObject[] newChildren = NotificationUtilities.getAddedChildren(notification); for (int iChild = 0; iChild < newChildren.length; iChild++) { childModelNode = getModelNode(packageDiagramModelNode, newChildren[iChild]); if (childModelNode == null) { childModelNode = getGenerator().createModel(newChildren[iChild], (Diagram)packageDiagramModelNode.getModelObject()); if (childModelNode != null) { childModelNode.setParent(packageDiagramModelNode); childModelNode.setPosition(getStartingPoint()); packageDiagramModelNode.addChild(childModelNode); performedChange = true; if (childModelNode.getAssociations(getNodeMap(packageDiagramModelNode)) != null) { hasAssociations = true; } } } } } if (performedChange && hasAssociations) updateAssociations(packageDiagramModelNode, packageDiagramModelNode); } } } private void performRemove( Notification notification, DiagramModelNode packageDiagramModelNode ) { if (NotificationUtilities.isEObjectNotifier(notification)) { // we know that the object is not a child of a model resource !!!!! EObject targetObject = NotificationUtilities.getEObject(notification); DiagramModelNode parentNode = getModelNode(packageDiagramModelNode, targetObject); DiagramModelNode removedNode = null; EObject[] removedChildren = NotificationUtilities.getRemovedChildren(notification); for (int iChild = 0; iChild < removedChildren.length; iChild++) { removedNode = getModelNode(packageDiagramModelNode, removedChildren[iChild]); if (removedNode != null) { if (parentNode != null) { if (!(parentNode instanceof UmlClassifierNode)) { parentNode.removeChild(removedNode, false); } // updateAssociations(parentNode, packageDiagramModelNode); // performedChange = true; } else { removeAllAssociationsFromNode(removedNode, packageDiagramModelNode); packageDiagramModelNode.removeChild(removedNode, true); // updateAssociations(removedNode, packageDiagramModelNode); } } } if (parentNode instanceof UmlClassifierNode) { addReconcileClassifier(parentNode); // ((UmlClassifierNode)parentNode).reconcile(); } } else { Diagram diagram = (Diagram)packageDiagramModelNode.getModelObject(); EObject diagramTargetEObject = diagram.getTarget(); Resource diagramModelResource = null; if (diagramTargetEObject instanceof ModelAnnotation) diagramModelResource = diagramTargetEObject.eResource(); // target of notification (notifier) is ModelResource Object changedObj = ModelerCore.getModelEditor().getChangedObject(notification); if (diagramModelResource != null && changedObj != null && changedObj instanceof Resource) { Resource targetResource = (Resource)changedObj; if (targetResource.equals(diagramModelResource)) { // We have a match, get the added children and hand them off to the generator to construct // and add to this packageDiagramModelNode DiagramModelNode removedNode = null; EObject[] removedChildren = NotificationUtilities.getRemovedChildren(notification); for (int iChild = 0; iChild < removedChildren.length; iChild++) { removedNode = getModelNode(packageDiagramModelNode, removedChildren[iChild]); if (removedNode != null) { removeAllAssociationsFromNode(removedNode, packageDiagramModelNode); packageDiagramModelNode.removeChild(removedNode, true); // updateAssociations(removedNode, packageDiagramModelNode); // performedChange = true; } } } } } } protected void performChange( Notification notification, DiagramModelNode packageDiagramModelNode ) { EObject targetObject = NotificationUtilities.getEObject(notification); if (notification.getEventType() == Notification.MOVE) { DiagramModelNode targetNode = getModelNode(packageDiagramModelNode, targetObject); if (targetNode != null) { targetNode.updateForChild(true); } } else if (targetObject instanceof Diagram) { if (notification.getNewValue() instanceof DiagramLinkType) { String newValue = ((DiagramLinkType)notification.getNewValue()).getName(); String oldValue = null; if (notification.getOldValue() instanceof DiagramLinkType) oldValue = ((DiagramLinkType)notification.getOldValue()).getName(); packageDiagramModelNode.update(DiagramUiConstants.DiagramNodeProperties.ROUTER, oldValue, newValue); } } else { DiagramModelNode targetNode = getModelNode(packageDiagramModelNode, targetObject); if (targetNode != null) { // If object's parent is in our current model // Assume this is a rename for now. getGenerator().performUpdate(targetNode, notification); // Check to see if eObject is of type UmlAssociation object if (getGenerator().isAssociation(targetObject)) { DiagramModelNode topClassNode = DiagramUiUtilities.getTopClassifierParentNode(targetNode); if (topClassNode != null) updateAssociations(topClassNode, packageDiagramModelNode); // updateAssociations(packageDiagramModelNode, packageDiagramModelNode); DiagramUiUtilities.hiliteCurrentSelectionDependencies(); } else { if (notification.getEventType() == Notification.REMOVE || notification.getEventType() == Notification.ADD) { // Assume that supertype is changed??? so DiagramModelNode topClassNode = DiagramUiUtilities.getTopClassifierParentNode(targetNode); if (topClassNode != null) updateAssociations(topClassNode, packageDiagramModelNode); } } } } } protected boolean associationExists( DiagramModelNode diagramModelNode, NodeConnectionModel targetAssociation ) { // get all connections from model List currentChildren = diagramModelNode.getChildren(); Iterator iter = currentChildren.iterator(); while (iter.hasNext()) { DiagramModelNode childModelNode = (DiagramModelNode)iter.next(); List sourceConnections = childModelNode.getSourceConnections(); // Walk through the source connections and check if the same info. NodeConnectionModel nextAssociation = null; Iterator sIter = sourceConnections.iterator(); while (sIter.hasNext()) { nextAssociation = (NodeConnectionModel)sIter.next(); if (associationsMatch(targetAssociation, nextAssociation)) return true; } // Walk through the target connections and check if the same info. List targetConnections = childModelNode.getTargetConnections(); sIter = targetConnections.iterator(); while (sIter.hasNext()) { nextAssociation = (NodeConnectionModel)sIter.next(); if (associationsMatch(targetAssociation, nextAssociation)) return true; } } return false; } protected boolean associationsMatch( NodeConnectionModel associationOne, NodeConnectionModel associationTwo ) { if (associationOne.getSourceNode().equals(associationTwo.getSourceNode()) && associationOne.getTargetNode().equals(associationTwo.getTargetNode())) return true; if (associationTwo.getSourceNode().equals(associationOne.getSourceNode()) && associationTwo.getTargetNode().equals(associationOne.getTargetNode())) return true; return false; } protected List getStaleAssociations( List expectedAssociations, DiagramModelNode diagramModelNode ) { List currentAssociations = getCurrentAssociations(diagramModelNode); if (currentAssociations.isEmpty()) return Collections.EMPTY_LIST; return getStaleAssociations(expectedAssociations, currentAssociations); } protected List getStaleAssociations( List expectedAssociations, List currentAssociations ) { List staleAssociations = new ArrayList(); // get all connections from model // walk through expected associations. Iterator iter = currentAssociations.iterator(); Iterator expectedIter = null; NodeConnectionModel nextCurrentAssociation = null; NodeConnectionModel nextExpectedAssociation = null; boolean foundMatch = false; while (iter.hasNext()) { foundMatch = false; nextCurrentAssociation = (NodeConnectionModel)iter.next(); expectedIter = expectedAssociations.iterator(); while (expectedIter.hasNext() && !foundMatch) { nextExpectedAssociation = (NodeConnectionModel)expectedIter.next(); if (associationsMatch(nextExpectedAssociation, nextCurrentAssociation)) { foundMatch = true; } } if (!foundMatch) { staleAssociations.add(nextCurrentAssociation); } } return staleAssociations; } protected List getCurrentAssociations( DiagramModelNode diagramModelNode ) { List currentAssociations = new ArrayList(); Iterator iter = diagramModelNode.getChildren().iterator(); while (iter.hasNext()) { DiagramModelNode childModelNode = (DiagramModelNode)iter.next(); List sourceConnections = childModelNode.getSourceConnections(); // Walk through the source connections and check if the same info. NodeConnectionModel nextAssociation = null; Iterator sIter = sourceConnections.iterator(); while (sIter.hasNext()) { nextAssociation = (NodeConnectionModel)sIter.next(); if (!currentAssociations.contains(nextAssociation)) currentAssociations.add(nextAssociation); } // Walk through the target connections and check if the same info. List targetConnections = childModelNode.getTargetConnections(); sIter = targetConnections.iterator(); while (sIter.hasNext()) { nextAssociation = (NodeConnectionModel)sIter.next(); if (!currentAssociations.contains(nextAssociation)) currentAssociations.add(nextAssociation); } } return currentAssociations; } protected List cleanUpStaleAssociations( List staleAssociations, DiagramModelNode diagramModelNode ) { HashMap updatedNodes = new HashMap(); Iterator iter = staleAssociations.iterator(); NodeConnectionModel nextAssociation = null; while (iter.hasNext()) { nextAssociation = (NodeConnectionModel)iter.next(); ((DiagramModelNode)nextAssociation.getSourceNode()).removeSourceConnection(nextAssociation); ((DiagramModelNode)nextAssociation.getTargetNode()).removeTargetConnection(nextAssociation); if (updatedNodes.get(nextAssociation.getSourceNode()) == null) updatedNodes.put(nextAssociation.getSourceNode(), "x"); //$NON-NLS-1$ if (updatedNodes.get(nextAssociation.getTargetNode()) == null) updatedNodes.put(nextAssociation.getTargetNode(), "x"); //$NON-NLS-1$ List labelNodes = nextAssociation.getLabelNodes(); if (labelNodes != null && !labelNodes.isEmpty()) { Iterator labelIter = labelNodes.iterator(); LabelModelNode nextNode = null; while (labelIter.hasNext()) { nextNode = (LabelModelNode)labelIter.next(); diagramModelNode.removeChild(nextNode, false); } } } return new ArrayList(updatedNodes.keySet()); } protected void removeAllAssociationsFromNode( DiagramModelNode diagramModelNode, DiagramModelNode diagramNode ) { // We assume here that we are removing this object from the diagram List sourceConnections = new ArrayList(diagramModelNode.getSourceConnections()); Iterator iter = sourceConnections.iterator(); NodeConnectionModel nextAssociation = null; DiagramModelNode otherNode = null; while (iter.hasNext()) { nextAssociation = (NodeConnectionModel)iter.next(); otherNode = ((DiagramModelNode)nextAssociation.getTargetNode()); diagramModelNode.removeSourceConnection(nextAssociation); otherNode.removeTargetConnection(nextAssociation); diagramModelNode.updateAssociations(); otherNode.updateAssociations(); List labelNodes = nextAssociation.getLabelNodes(); if (labelNodes != null && !labelNodes.isEmpty()) { Iterator labelIter = labelNodes.iterator(); LabelModelNode nextNode = null; while (labelIter.hasNext()) { nextNode = (LabelModelNode)labelIter.next(); diagramNode.removeChild(nextNode, false); } } } List targetConnections = new ArrayList(diagramModelNode.getTargetConnections()); iter = targetConnections.iterator(); nextAssociation = null; while (iter.hasNext()) { nextAssociation = (NodeConnectionModel)iter.next(); otherNode = ((DiagramModelNode)nextAssociation.getSourceNode()); diagramModelNode.removeTargetConnection(nextAssociation); otherNode.removeSourceConnection(nextAssociation); diagramModelNode.updateAssociations(); otherNode.updateAssociations(); List labelNodes = nextAssociation.getLabelNodes(); if (labelNodes != null && !labelNodes.isEmpty()) { Iterator labelIter = labelNodes.iterator(); LabelModelNode nextNode = null; while (labelIter.hasNext()) { nextNode = (LabelModelNode)labelIter.next(); diagramNode.removeChild(nextNode, false); } } } } protected void updateAssociations( DiagramModelNode diagramModelNode, DiagramModelNode diagramNode ) { HashMap nodeMap = getNodeMap(diagramNode); String currentRouterStyle = DiagramLinkType.get(DiagramEditorUtil.getCurrentDiagramRouterStyle()).getName(); if (diagramModelNode instanceof PackageDiagramNode) { // Need to get new list of associations that should exist between visible components. // Let's get contents, and get associations for each object NodeConnectionModel nextAssociation = null; List realAssociations = new ArrayList(); List currentChildren = diagramModelNode.getChildren(); Iterator iter = currentChildren.iterator(); while (iter.hasNext()) { DiagramModelNode childModelNode = (DiagramModelNode)iter.next(); if (childModelNode != null) { List allAssociations = childModelNode.getAssociations(nodeMap); if (allAssociations != null && !allAssociations.isEmpty()) { Iterator subIter = allAssociations.iterator(); Object nextAss = null; while (subIter.hasNext()) { nextAss = subIter.next(); if (!realAssociations.contains(nextAss)) { realAssociations.add(nextAss); } } } } } // Remove old associations. List staleAssociations = getStaleAssociations(realAssociations, diagramModelNode); List changedNodes = new ArrayList(cleanUpStaleAssociations(staleAssociations, diagramModelNode)); HashMap updatedNodes = new HashMap(); iter = changedNodes.iterator(); while (iter.hasNext()) { updatedNodes.put(iter.next(), "x"); //$NON-NLS-1$ } // Add new associations if they don't exist. iter = realAssociations.iterator(); while (iter.hasNext()) { nextAssociation = (NodeConnectionModel)iter.next(); if (!associationExists(diagramModelNode, nextAssociation)) { if (nextAssociation.getDiagramLink() == null) nextAssociation.setRouterStyle(currentRouterStyle); ((DiagramModelNode)nextAssociation.getSourceNode()).addSourceConnection(nextAssociation); ((DiagramModelNode)nextAssociation.getTargetNode()).addTargetConnection(nextAssociation); // Keep a list of new end nodes so we can tell them to fire // an updateAssociations() call... if (updatedNodes.get(nextAssociation.getSourceNode()) == null) updatedNodes.put(nextAssociation.getSourceNode(), "x"); //$NON-NLS-1$ if (updatedNodes.get(nextAssociation.getTargetNode()) == null) updatedNodes.put(nextAssociation.getTargetNode(), "x"); //$NON-NLS-1$ List labelNodes = nextAssociation.getLabelNodes(); if (labelNodes != null && !labelNodes.isEmpty()) { Iterator labelIter = labelNodes.iterator(); LabelModelNode nextNode = null; while (labelIter.hasNext()) { nextNode = (LabelModelNode)labelIter.next(); diagramModelNode.addChild(nextNode); } } } } // call updateLabels in case info changes. (i.e names, labels, etc...) iter = getCurrentAssociations(diagramModelNode).iterator(); while (iter.hasNext()) { nextAssociation = (NodeConnectionModel)iter.next(); nextAssociation.updateLabels(); ((DiagramModelNode)nextAssociation.getSourceNode()).updateAssociations(); ((DiagramModelNode)nextAssociation.getTargetNode()).updateAssociations(); } if (!updatedNodes.isEmpty()) { iter = updatedNodes.keySet().iterator(); DiagramModelNode nextNode = null; while (iter.hasNext()) { nextNode = (DiagramModelNode)iter.next(); nextNode.updateAssociations(); } } } else if (diagramModelNode instanceof UmlClassifierNode) { NodeConnectionModel nextAssociation = null; List realAssociations = new ArrayList(); List allAssociations = diagramModelNode.getAssociations(nodeMap); if (allAssociations != null && !allAssociations.isEmpty()) { Iterator subIter = allAssociations.iterator(); Object nextAss = null; while (subIter.hasNext()) { nextAss = subIter.next(); if (!realAssociations.contains(nextAss)) { realAssociations.add(nextAss); } } } List currentAssociations = new ArrayList(); List sourceConnections = diagramModelNode.getSourceConnections(); // Walk through the source connections and check if the same info. Iterator sIter = sourceConnections.iterator(); while (sIter.hasNext()) { nextAssociation = (NodeConnectionModel)sIter.next(); if (!currentAssociations.contains(nextAssociation)) currentAssociations.add(nextAssociation); } // Walk through the target connections and check if the same info. List targetConnections = diagramModelNode.getTargetConnections(); sIter = targetConnections.iterator(); while (sIter.hasNext()) { nextAssociation = (NodeConnectionModel)sIter.next(); if (!currentAssociations.contains(nextAssociation)) currentAssociations.add(nextAssociation); } List staleAssociations = getStaleAssociations(realAssociations, currentAssociations); List changedNodes = new ArrayList(cleanUpStaleAssociations(staleAssociations, diagramNode)); HashMap updatedNodes = new HashMap(); // Put the node in that started this whole process. updatedNodes.put(diagramModelNode, "x"); //$NON-NLS-1$ Iterator iter = changedNodes.iterator(); while (iter.hasNext()) { updatedNodes.put(iter.next(), "x"); //$NON-NLS-1$ } updateNodeAssociations(updatedNodes.keySet()); updatedNodes = new HashMap(); // Put the node in that started this whole process. updatedNodes.put(diagramModelNode, "x"); //$NON-NLS-1$ // Add new associations if they don't exist. iter = realAssociations.iterator(); while (iter.hasNext()) { nextAssociation = (NodeConnectionModel)iter.next(); if (nextAssociation.getDiagramLink() == null) nextAssociation.setRouterStyle(currentRouterStyle); if (!associationExists(diagramNode, nextAssociation)) { ((DiagramModelNode)nextAssociation.getSourceNode()).addSourceConnection(nextAssociation); ((DiagramModelNode)nextAssociation.getTargetNode()).addTargetConnection(nextAssociation); // Keep a list of new end nodes so we can tell them to fire // an updateAssociations() call... if (updatedNodes.get(nextAssociation.getSourceNode()) == null) updatedNodes.put(nextAssociation.getSourceNode(), "x"); //$NON-NLS-1$ if (updatedNodes.get(nextAssociation.getTargetNode()) == null) updatedNodes.put(nextAssociation.getTargetNode(), "x"); //$NON-NLS-1$ List labelNodes = nextAssociation.getLabelNodes(); if (labelNodes != null && !labelNodes.isEmpty()) { Iterator labelIter = labelNodes.iterator(); LabelModelNode nextNode = null; while (labelIter.hasNext()) { nextNode = (LabelModelNode)labelIter.next(); diagramNode.addChild(nextNode); } } } } // call updateLabels in case info changes. (i.e names, labels, etc...) iter = getCurrentAssociations(diagramNode).iterator(); while (iter.hasNext()) { nextAssociation = (NodeConnectionModel)iter.next(); nextAssociation.updateLabels(); // ((DiagramModelNode)nextAssociation.getSourceNode()).updateAssociations(); // ((DiagramModelNode)nextAssociation.getTargetNode()).updateAssociations(); } updateNodeAssociations(updatedNodes.keySet()); } } protected void updateNodeAssociations( Set diagramModelNodes ) { if (!diagramModelNodes.isEmpty()) { Iterator iter = diagramModelNodes.iterator(); DiagramModelNode nextNode = null; while (iter.hasNext()) { nextNode = (DiagramModelNode)iter.next(); // if( !nextNode.equals(diagramModelNode)) nextNode.updateAssociations(); nextNode.update(DiagramUiConstants.DiagramNodeProperties.BENDPOINT); } } } @Override public String toString() { return "PackageDiagamModelFactory()"; //$NON-NLS-1$ } private Point getStartingPoint() { Point thisPoint = new Point(startingPoint); // Now we increment the point if (startingPoint.x < X_MAX) { startingPoint.x += X_INC; startingPoint.y += Y_INC; } else { yInc += 20; startingPoint.x = I_BORDER; startingPoint.y = yInc; } return thisPoint; } /** * Method which determines whether this EObject can be represented in a diagram or not. * * @return boolean */ @Override public boolean isDrawable( EObject eObject ) { boolean result = true; if (eObject instanceof JdbcSource) result = false; return result; } protected HashMap getNodeMap( DiagramModelNode diagramNode ) { HashMap nodeMap = new HashMap(); Iterator iter = diagramNode.getChildren().iterator(); DiagramModelNode dmn = null; while (iter.hasNext()) { dmn = (DiagramModelNode)iter.next(); if (dmn.getModelObject() != null) nodeMap.put(dmn.getModelObject(), dmn); } return nodeMap; } /** * @return */ public String getSNotationId() { return sNotationId; } /** * @param string */ public void setSNotationId( String string ) { sNotationId = string; } private void addReconcileClassifier( DiagramModelNode classifierNode ) { if (reconcileClassifierNodes == null) reconcileClassifierNodes = new HashMap(); if (reconcileClassifierNodes.get(classifierNode) == null) reconcileClassifierNodes.put(classifierNode, "x"); //$NON-NLS-1$ } private void reconcileClassifiers( DiagramModelNode packageDiagramNode ) { if (reconcileClassifierNodes != null && !reconcileClassifierNodes.isEmpty()) { UmlClassifierNode nextNode = null; for (Iterator iter = reconcileClassifierNodes.keySet().iterator(); iter.hasNext();) { nextNode = (UmlClassifierNode)iter.next(); nextNode.reconcile(); // Call update on the classifier's children DiagramModelNode dNode = null; for (Iterator iter2 = nextNode.getChildren().iterator(); iter2.hasNext();) { dNode = (DiagramModelNode)iter2.next(); dNode.update(DiagramUiConstants.DiagramNodeProperties.CHILDREN); dNode.update(DiagramUiConstants.DiagramNodeProperties.LAYOUT); } nextNode.update(DiagramUiConstants.DiagramNodeProperties.CHILDREN); // nextNode.update(DiagramUiConstants.DiagramNodeProperties.SIZE); nextNode.update(DiagramUiConstants.DiagramNodeProperties.LAYOUT); updateAssociations(nextNode, packageDiagramNode); } } reconcileClassifierNodes = null; } @Override public boolean shouldRefreshDiagram(Notification notification, DiagramModelNode diagramModelNode, String sDiagramTypeId) { if( notification instanceof SourcedNotification ) { SourcedNotification sNot = (SourcedNotification)notification; if( sNot.getSource() instanceof DefaultIgnorableNotificationSource) { DefaultIgnorableNotificationSource isrc = (DefaultIgnorableNotificationSource)sNot.getSource(); if( isrc.getActualSource().getClass().getName().indexOf("JdbcImportWizard") > -1 && //$NON-NLS-1$ isrc.getSourceIdentifier() != null) { // Check same model name String mrName = ModelUtilities.getModelResource(diagramModelNode.getModelObject()).getItemName(); if( mrName.equalsIgnoreCase(isrc.getSourceIdentifier())) { return true; } } } } return false; } }