/* * 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 org.savara.bpmn2.internal.generation.BPMN2GenerationException; import org.savara.common.model.annotation.Annotation; import org.savara.common.model.annotation.AnnotationDefinitions; import org.scribble.protocol.model.Interaction; /** * This class represents the state information associated with * the construction of a BPMN Activity model. * */ public class BPMNDiagram extends AbstractBPMNActivity { private Object m_diagram=null; private Object m_container=null; private java.util.Map<String,BPMNActivity> m_sendActivities=new java.util.HashMap<String,BPMNActivity>(); private java.util.Map<String,BPMNActivity> m_receiveActivities=new java.util.HashMap<String,BPMNActivity>(); private java.util.Map<String,BPMNPool> m_pools=new java.util.HashMap<String,BPMNPool>(); private java.util.List<BPMNPool> m_duplicatePools=new java.util.Vector<BPMNPool>(); private boolean m_sendReceiveAsControlLink=true; private boolean m_controlFromSendOnly=false; /** * This is the constructor for the activity model. * * @param choreoName The choreography name * @param diagramName The diagram name * @param parent The parent activity * @param model The model factory * @param folder The output folder * @exception BPMN2GenerationException Failed to construct activity model */ public BPMNDiagram(String choreoName, String diagramName, BPMNActivity parent, org.savara.bpmn2.internal.generation.BPMN2ModelFactory model, org.savara.bpmn2.internal.generation.BPMN2NotationFactory notation) throws BPMN2GenerationException { super(parent, model, notation); m_diagram = model.createDiagram(); } /** * This method returns the container associated with the * activity. * * @return The container */ public Object getContainer() { return(m_container); } /** * This method sets the container associated with the * BPMN model. * * @param container The container */ public BPMNPool createPool(String participant) { BPMNPool ret=new BPMNPool(m_diagram, participant, this, getModelFactory(), getNotationFactory()); if (m_pools.containsKey(participant)) { m_duplicatePools.add(ret); } else { m_pools.put(participant, ret); } return(ret); } /** * This method sets the container associated with the * BPMN model. * * @param container The container */ public Choreography createChoreography(String choreoName) { Choreography ret=new Choreography(m_diagram, choreoName, this, getModelFactory(), getNotationFactory()); return(ret); } /** * This method determines whether the supplied behavior type * should result in a root entry/exit point from the * state machine. * * @param elem The behavior type * @return Whether it is a root */ /* protected boolean isRoot(Activity elem) { boolean ret=false; if (elem instanceof Protocol && ((Protocol)elem).getParent() instanceof ProtocolModel) { ret = true; } return(ret); } */ /** * This method returns the containing ActivityModel. * * @return The activity model */ public BPMNDiagram getBPMNDiagram() { return(this); } /** * This method returns the start node for the activites * represented by this BPMN activity implementation. * * @return The starting node */ public Object getStartNode() { //return(m_initialState.getStartNode()); return(null); } /** * This method returns the end node for the activities * represented by this BPMN activity implementation. * * @return The ending node */ public Object getEndNode() { //return(m_finalState.getEndNode()); return(null); } /** * This method returns the start state. * * @return The start state */ public BPMNActivity getStartState() { return(null); } /** * This method returns the end state. * * @return The end state */ public BPMNActivity getEndState() { return(null); } /** * This method registers a send activity against the BPMN representation. * * @param send The send activity * @param activity The BPMN representation */ public void registerSendActivity(Interaction send, BPMNActivity activity) { if (isPoolDuplicate(activity) == false) { Annotation ann=AnnotationDefinitions.getAnnotation(send.getAnnotations(), AnnotationDefinitions.SOURCE_COMPONENT); if (ann != null && ann.getProperties().containsKey(AnnotationDefinitions.ID_PROPERTY)) { m_sendActivities.put((String)ann.getProperties().get(AnnotationDefinitions.ID_PROPERTY), activity); } } } /** * This method registers a receive activity against the BPMN representation. * * @param recv The receive activity * @param activity The BPMN representation */ public void registerReceiveActivity(Interaction recv, BPMNActivity activity) { if (isPoolDuplicate(activity) == false) { Annotation ann=AnnotationDefinitions.getAnnotation(recv.getAnnotations(), AnnotationDefinitions.SOURCE_COMPONENT); if (ann != null && ann.getProperties().containsKey(AnnotationDefinitions.ID_PROPERTY)) { m_receiveActivities.put((String)ann.getProperties().get(AnnotationDefinitions.ID_PROPERTY), activity); } } } /** * This method determines if the supplied activity is * associated with a duplicate pool that will be deleted. * * @param activity The activity * @return Whether the activity is associated with a * duplicate pool */ protected boolean isPoolDuplicate(BPMNActivity activity) { boolean ret=false; while (activity != null && (activity instanceof BPMNPool) == false) { activity = activity.getParent(); } if (activity != null) { ret = m_duplicatePools.contains(activity); } return(ret); } /** * This method completes the generation of the model. * */ public void completeModel() { java.util.Iterator<String> iter=m_sendActivities.keySet().iterator(); java.util.List<Object> messageLinks=new java.util.ArrayList<Object>(); while (iter.hasNext()) { String sendId=iter.next(); BPMNActivity sendActivity=(BPMNActivity) m_sendActivities.get(sendId); ReceiveActivity receiveActivity=(ReceiveActivity) m_receiveActivities.get(sendId); if (sendActivity != null && receiveActivity != null) { if (m_sendReceiveAsControlLink) { if (m_controlFromSendOnly) { // Break links to the receive node, as control will // be from the sending participant receiveActivity.breakLinks(); } // Create control flow between the activities messageLinks.add(getModelFactory(). createMessageLink(m_diagram, sendActivity.getEndNode(), receiveActivity.getStartNode(), receiveActivity.getReceive())); // Check if the receive and send activities have a link to the // same node, in which case remove the link from the send checkForRedundantTargetLinks(sendActivity, receiveActivity); } } } // Delete duplicate pools for (int i=0; i < m_duplicatePools.size(); i++) { BPMNPool pool=(BPMNPool)m_duplicatePools.get(i); getModelFactory().delete(pool.getContainer()); getChildStates().remove(pool); } // Draw diagram int cury=0; for (int i=0; i < getChildStates().size(); i++) { BPMNActivity act=getChildStates().get(i); act.calculatePosition(0, cury); cury += (act.getHeight()+100); } //getModelFactory().saveModel(m_folder+ // java.io.File.separator+m_name+"."+ // getModelFactory().getFileExtension(), m_diagram); // Construct notation Object diagramNotation=getNotationFactory().createDiagram(getModelFactory(), m_diagram, getX(), getY(), getWidth(), getHeight()); for (int i=0; i < getChildStates().size(); i++) { getChildStates().get(i).draw(diagramNotation); } } protected void checkForRedundantTargetLinks(BPMNActivity source, BPMNActivity target) { // Check if the target and source activities have a link to the // same node, in which case remove the link from the source java.util.List<Object> outgoing1=getModelFactory().getOutboundControlLinks(target.getStartNode()); for (int i=0; i < outgoing1.size(); i++) { Object ae1=outgoing1.get(i); java.util.List<Object> outgoing2=getModelFactory().getOutboundControlLinks(source.getStartNode()); boolean f_found=false; for (int j=0; f_found==false && j < outgoing2.size(); j++){ Object ae2=outgoing2.get(j); if (getModelFactory().getTarget(ae1) == getModelFactory().getTarget(ae2)) { f_found = true; getModelFactory().delete(ae2); } } } } }