blob: 00bda91ffe1cf953e8f02b854aefea22e4b25bdc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.gmf.examples.runtime.diagram.logic.internal.wizards;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.emf.transaction.impl.EMFCommandTransaction;
import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.examples.runtime.diagram.logic.internal.editparts.CircuitEditPart;
import org.eclipse.gmf.examples.runtime.diagram.logic.internal.editparts.TerminalEditPart;
import org.eclipse.gmf.examples.runtime.diagram.logic.internal.providers.LogicConstants;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.AndGate;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.Circuit;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.Element;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.InputTerminal;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.LED;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.Model;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.OrGate;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.OutputTerminal;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.Wire;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.XORGate;
import org.eclipse.gmf.examples.runtime.diagram.logic.semantic.util.LogicSemanticType;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequestFactory;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest.ViewAndElementDescriptor;
import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateRelationshipRequest;
/**
* Factory for creating contents of example logic diagrams.
*
* @author mgobeil
*/
public class LogicDiagramFactory {
public static void CreateFourBitAdder(IGraphicalEditPart diagramEditPart,
IProgressMonitor progressMonitor) {
// create logic elements
Circuit fullAdder1 = createFullAdder(new Point(20, 120), new Dimension(
140, 230), diagramEditPart, progressMonitor);
Circuit fullAdder2 = createFullAdder(new Point(170, 120),
new Dimension(140, 230), diagramEditPart, progressMonitor);
Circuit fullAdder3 = createFullAdder(new Point(320, 120),
new Dimension(140, 230), diagramEditPart, progressMonitor);
Circuit halfAdder = createHalfAdder(new Point(470, 120), new Dimension(
70, 230), diagramEditPart, progressMonitor);
// chain carry bits
connect(outputTerminal(fullAdder1, 3), inputTerminal(fullAdder2, 4),
diagramEditPart, progressMonitor);
connect(outputTerminal(fullAdder2, 3), inputTerminal(fullAdder3, 4),
diagramEditPart, progressMonitor);
connect(outputTerminal(fullAdder3, 3), inputTerminal(halfAdder, 4),
diagramEditPart, progressMonitor);
// create and connect led input 1
final LED ledInput1 = createElement(LogicSemanticType.LED, LED.class,
new Point(150, 20), diagramEditPart, progressMonitor);
connect(outputTerminal(ledInput1, 3), inputTerminal(fullAdder1, 0),
diagramEditPart, progressMonitor);
connect(outputTerminal(ledInput1, 2), inputTerminal(fullAdder2, 0),
diagramEditPart, progressMonitor);
connect(outputTerminal(ledInput1, 1), inputTerminal(fullAdder3, 0),
diagramEditPart, progressMonitor);
connect(outputTerminal(ledInput1, 0), inputTerminal(halfAdder, 0),
diagramEditPart, progressMonitor);
// create and connect led input 2
final LED ledInput2 = createElement(LogicSemanticType.LED, LED.class,
new Point(350, 20), diagramEditPart, progressMonitor);
connect(outputTerminal(ledInput2, 3), inputTerminal(fullAdder1, 2),
diagramEditPart, progressMonitor);
connect(outputTerminal(ledInput2, 2), inputTerminal(fullAdder2, 2),
diagramEditPart, progressMonitor);
connect(outputTerminal(ledInput2, 1), inputTerminal(fullAdder3, 2),
diagramEditPart, progressMonitor);
connect(outputTerminal(ledInput2, 0), inputTerminal(halfAdder, 3),
diagramEditPart, progressMonitor);
// create and connect led output
LED ledOutput = createElement(LogicSemanticType.LED, LED.class,
new Point(250, 400), diagramEditPart, progressMonitor);
connect(outputTerminal(fullAdder1, 7), inputTerminal(ledOutput, 3),
diagramEditPart, progressMonitor);
connect(outputTerminal(fullAdder2, 7), inputTerminal(ledOutput, 2),
diagramEditPart, progressMonitor);
connect(outputTerminal(fullAdder3, 7), inputTerminal(ledOutput, 1),
diagramEditPart, progressMonitor);
connect(outputTerminal(halfAdder, 7), inputTerminal(ledOutput, 0),
diagramEditPart, progressMonitor);
// set the input values
org.eclipse.emf.common.command.Command cmd = new org.eclipse.emf.common.command.AbstractCommand() {
public void execute() {
ledInput1.setValue(3);
ledInput2.setValue(7);
}
public void redo() {
execute();
}
};
EMFCommandTransaction trans = new EMFCommandTransaction(cmd,
(InternalTransactionalEditingDomain) diagramEditPart
.getEditingDomain(), null);
try {
trans.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
trans.getCommand().execute();
try {
trans.commit();
} catch (RollbackException e) {
e.printStackTrace();
}
}
public static Circuit createFullAdder(Point location, Dimension size,
IGraphicalEditPart containerEditPart,
IProgressMonitor progressMonitor) {
Circuit circuit = createElement(LogicSemanticType.CIRCUIT,
Circuit.class, location, size, containerEditPart,
progressMonitor);
CircuitEditPart circuitEditPart = getEditPart(circuit,
CircuitEditPart.class, containerEditPart);
Circuit halfAdder1 = createHalfAdder(new Point(10, 10),
circuitEditPart, progressMonitor);
Circuit halfAdder2 = createHalfAdder(new Point(50, 100),
circuitEditPart, progressMonitor);
OrGate orGate = createElement(LogicSemanticType.ORGATE, OrGate.class,
new Point(40, 180), circuitEditPart, progressMonitor);
;
// input to first half adder
connect(outputTerminal(circuit, 0), inputTerminal(halfAdder1, 0),
circuitEditPart, progressMonitor);
connect(outputTerminal(circuit, 2), inputTerminal(halfAdder1, 3),
circuitEditPart, progressMonitor);
// input to second half adder
connect(outputTerminal(circuit, 3), inputTerminal(halfAdder2, 3),
circuitEditPart, progressMonitor);
connect(outputTerminal(halfAdder1, 7), inputTerminal(halfAdder2, 0),
circuitEditPart, progressMonitor);
// input to OR gate
connect(outputTerminal(halfAdder1, 4), inputTerminal(orGate, 0),
circuitEditPart, progressMonitor);
connect(outputTerminal(halfAdder2, 4), inputTerminal(orGate, 1),
circuitEditPart, progressMonitor);
// output of circuit
connect(outputTerminal(orGate, 0), inputTerminal(circuit, 4),
circuitEditPart, progressMonitor);
connect(outputTerminal(halfAdder2, 7), inputTerminal(circuit, 7),
circuitEditPart, progressMonitor);
return circuit;
}
public static Circuit createHalfAdder(Point location,
IGraphicalEditPart containerEditPart,
IProgressMonitor progressMonitor) {
return createHalfAdder(location, new Dimension(70, 70),
containerEditPart, progressMonitor);
}
public static Circuit createHalfAdder(Point location, Dimension size,
IGraphicalEditPart containerEditPart,
IProgressMonitor progressMonitor) {
Circuit circuit = createElement(LogicSemanticType.CIRCUIT,
Circuit.class, location, size, containerEditPart,
progressMonitor);
CircuitEditPart circuitEditPart = getEditPart(circuit,
CircuitEditPart.class, containerEditPart);
AndGate andGate = createElement(LogicSemanticType.ANDGATE,
AndGate.class, new Point(10, 20), circuitEditPart,
progressMonitor);
;
XORGate xorGate = createElement(LogicSemanticType.XORGATE,
XORGate.class, new Point(40, 20), circuitEditPart,
progressMonitor);
;
connect(outputTerminal(circuit, 0), inputTerminal(andGate, 0),
circuitEditPart, progressMonitor);
connect(outputTerminal(circuit, 3), inputTerminal(andGate, 1),
circuitEditPart, progressMonitor);
connect(outputTerminal(circuit, 0), inputTerminal(xorGate, 0),
circuitEditPart, progressMonitor);
connect(outputTerminal(circuit, 3), inputTerminal(xorGate, 1),
circuitEditPart, progressMonitor);
connect(outputTerminal(andGate, 0), inputTerminal(circuit, 4),
circuitEditPart, progressMonitor);
connect(outputTerminal(xorGate, 0), inputTerminal(circuit, 7),
circuitEditPart, progressMonitor);
return circuit;
}
private static <T> T createElement(IElementType elementType,
Class<T> elementTypeClass, Point location,
IGraphicalEditPart container, IProgressMonitor progressMonitor) {
return createElement(elementType, elementTypeClass, location, null,
container, progressMonitor);
}
private static <T> T createElement(IElementType elementType,
Class<T> elementTypeClass, Point location, Dimension size,
IGraphicalEditPart container, IProgressMonitor progressMonitor) {
if (container instanceof CircuitEditPart) {
container = (IGraphicalEditPart) container
.getChildBySemanticHint(LogicConstants.LOGIC_SHAPE_COMPARTMENT);
}
CreateViewRequest createRequest = CreateViewRequestFactory
.getCreateShapeRequest(elementType, container
.getDiagramPreferencesHint());
createRequest.setLocation(location);
createRequest.setSize(size);
Command command = container.getCommand(createRequest);
container.getDiagramEditDomain().getDiagramCommandStack().execute(
command, progressMonitor);
List<IAdaptable> newObject = (List<IAdaptable>) createRequest
.getNewObject();
ViewAndElementDescriptor viewAndElementDescriptor = (ViewAndElementDescriptor) newObject
.get(0);
return (T) viewAndElementDescriptor.getElementAdapter().getAdapter(
elementTypeClass);
}
private static void connect(OutputTerminal outputTerminal,
InputTerminal inputTerminal, IGraphicalEditPart container,
IProgressMonitor progressMonitor) {
CreateRelationshipRequest createRequest = new CreateRelationshipRequest(
container.getEditingDomain(), outputTerminal, inputTerminal,
LogicSemanticType.WIRE);
IElementType elementType = ElementTypeRegistry.getInstance()
.getElementType(createRequest.getEditHelperContext());
ICommand createCommand = elementType.getEditCommand(createRequest);
try {
createCommand.execute(progressMonitor, null);
} catch (ExecutionException e) {
e.printStackTrace();
}
// HAAAACK! why won't the above command create a view when the parent is
// a Model instead of a Circuit?
if (createRequest.getContainer() instanceof Model) {
// get matching editparts for semantic terminals
TerminalEditPart outputTerminalEditPart = getEditPart(
outputTerminal, TerminalEditPart.class, container);
TerminalEditPart inputTerminalEditPart = getEditPart(inputTerminal,
TerminalEditPart.class, container);
// create matching notational wire connection
Command command = CreateConnectionViewRequest.getCreateCommand(
(Wire) createCommand.getCommandResult().getReturnValue(),
outputTerminalEditPart, inputTerminalEditPart, container
.getDiagramPreferencesHint());
container.getDiagramEditDomain().getDiagramCommandStack().execute(
command, progressMonitor);
}
}
private static OutputTerminal outputTerminal(Element element, int terminal) {
return (OutputTerminal) element.getOutputTerminals().get(terminal);
}
private static InputTerminal inputTerminal(Element element, int terminal) {
return (InputTerminal) element.getInputTerminals().get(terminal);
}
private static <T> T getEditPart(EObject modelElement,
Class<T> editPartType, IGraphicalEditPart container) {
if (container instanceof CircuitEditPart) {
container = (IGraphicalEditPart) container
.getChildBySemanticHint(LogicConstants.LOGIC_SHAPE_COMPARTMENT);
}
DiagramGraphicalViewer viewer = (DiagramGraphicalViewer) container
.getRoot().getViewer();
String proxyId = EMFCoreUtil.getProxyID(modelElement);
return (T) viewer.findEditPartsForElement(proxyId, editPartType).get(0);
}
}