/* * Copyright 2005-7 Pi4 Technologies Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * * Change History: * Jan 25, 2007 : Initial version created by gary */ package org.savara.bpmn2.internal.generation.components; import javax.xml.namespace.QName; import org.savara.bpmn2.model.BPMNEdge; import org.savara.bpmn2.model.Point; import org.savara.bpmn2.model.TBoundaryEvent; import org.scribble.protocol.model.Activity; /** * This class represents the BPMN activity node for a Perform activity. * */ public class DoActivity extends AbstractBPMNActivity { private boolean m_completed=false; private static final int CATCH_OFFSET=50; /** * This constructor initializes the receive state. * * @param act The behavioral activity * @param parent The parent BPMN state * @param model The BPMN model */ public DoActivity(Activity act, BPMNActivity parent, org.savara.bpmn2.internal.generation.BPMN2ModelFactory model, org.savara.bpmn2.internal.generation.BPMN2NotationFactory notation) { super(parent, model, notation); } /** * This method indicates that the BPMN state for the * child nodes is complete. * */ public void childrenComplete() { if (m_completed == false) { int height=0; int maxwidth=0; for (int i=0; i < getChildStates().size(); i++) { BPMNActivity act=(BPMNActivity)getChildStates().get(i); int width=act.getWidth(); if (i > 0) { width += (getChildStates().size()-i) * CATCH_OFFSET; } if (width > maxwidth) { maxwidth = width; } height += act.getHeight()+VERTICAL_GAP; } // Add padding setHeight(height-VERTICAL_GAP); setWidth(maxwidth+(HORIZONTAL_GAP*2)); m_completed = true; } } public void calculatePosition(int x, int y) { int curx=x+HORIZONTAL_GAP; int cury=y; setX(x); setY(y); //+VERTICAL_GAP); for (int i=0; i < getChildStates().size(); i++) { BPMNActivity act=(BPMNActivity)getChildStates().get(i); int newx=curx; if (i > 0) { newx += (getChildStates().size()-i) * CATCH_OFFSET; } act.calculatePosition(newx, cury); cury += act.getHeight()+VERTICAL_GAP; } } public void draw(Object parent) { DoBlockActivity tryblock=(DoBlockActivity)getChildStates().get(0); tryblock.draw(parent); for (int i=1; i < getChildStates().size(); i++) { BPMNActivity act=(BPMNActivity)getChildStates().get(i); act.draw(parent); if (i > 0) { TBoundaryEvent boundaryEvent=(TBoundaryEvent)getModelFactory().createBoundaryEvent(getContainer()); boundaryEvent.setAttachedToRef(new QName(getModelFactory().getDefinitions().getTargetNamespace(), tryblock.getSubProcess().getId())); getNotationFactory().createEvent(getModelFactory(), boundaryEvent, parent, tryblock.getX()+((getChildStates().size()-i-1)*CATCH_OFFSET), tryblock.getY()+tryblock.getHeight()-15, 30, 30); // Draw throw event to this catch block Object link=getModelFactory().createControlLink(getContainer(), boundaryEvent, act.getStartNode(), null); BPMNEdge edge=(BPMNEdge)getNotationFactory().createSequenceLink(getModelFactory(), link, parent); edge.getWaypoint().get(0).setX(edge.getWaypoint().get(0).getX()-15); edge.getWaypoint().get(0).setY(edge.getWaypoint().get(0).getY()+15); Point p1=new Point(); p1.setY(edge.getWaypoint().get(1).getY()); p1.setX(edge.getWaypoint().get(0).getX()); edge.getWaypoint().add(1, p1); } } } /** * This method causes the receive activity to break any * existing control links, including removing preceeding * nodes that only have these links as their outgoing * links. * */ public void breakLinks() { Object node=getStartNode(); java.util.List<Object> list=getModelFactory().getInboundControlLinks(node); for (int i=list.size()-1; i >= 0; i--) { Object edge=list.get(i); tidyUpEdge(edge); } } /** * This method tidies up an activity edge, recursively being * called if its source node only has a single incoming * activity edge. * * @param edge The activity edge */ protected void tidyUpEdge(Object edge) { // Check if source node has only a single incoming link // and if so, then remove the node Object sourceNode=getModelFactory().getSource(edge); getModelFactory().delete(edge); // If has less than 2 incoming links and no // outgoing link, then tidyup node and links recursively if (getModelFactory().getInboundControlLinks(sourceNode).size() <= 1 && getModelFactory().getOutboundControlLinks(sourceNode).size() == 0 && (getModelFactory().isDecision(sourceNode) || // was decision node getModelFactory().isJoin(sourceNode))) { // was merge node if (getModelFactory().getInboundControlLinks(sourceNode).size() == 1) { Object actedge=getModelFactory(). getInboundControlLinks(sourceNode).get(0); tidyUpEdge(actedge); } getModelFactory().delete(sourceNode); } } public Object getStartNode() { BPMNActivity act=(BPMNActivity)getChildStates().get(0); return(act.getStartNode()); } public Object getEndNode() { BPMNActivity act=(BPMNActivity)getChildStates().get(0); return(act.getEndNode()); } /** * This method returns the start state. * * @return The start state */ public BPMNActivity getStartState() { return(this); } /** * This method returns the end state. * * @return The end state */ public BPMNActivity getEndState() { return(this); } }