/****************************************************************************** * Copyright (c) 2010-2013, Linagora * * 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: * Linagora - initial API and implementation *******************************************************************************/ package com.ebmwebsourcing.petals.services.eip.designer.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.ebmwebsourcing.petals.common.internal.provisional.utils.StringUtils; /** * A connection between an EIP and an EIP or an end-point. * @author Vincent Zurczak - EBM WebSourcing */ public class EipConnection { public static final String PROPERTY_CONNECTION_SOURCE = "ConnectionSource"; public static final String PROPERTY_CONSUME_BY_ITF = "ConsumeByItf"; public static final String PROPERTY_CONSUME_BY_SRV = "ConsumeBySrv"; public static final String PROPERTY_CONSUME_BY_EDPT = "ConsumeByEdpt"; public static final String PROPERTY_CONSUMED_OPERATION = "ConsumedOperation"; public static final String PROPERTY_CONSUMED_MEP = "ConsumedMep"; public static final String PROPERTY_CONDITION_NAME = "ConditionName"; public static final String PROPERTY_CONDITION_EXPRESSION = "ConditionExpression"; public static final String PROPERTY_ERROR = "ConnectionError"; private final PropertyChangeSupport listeners; private boolean alreadyConnected = false; private final List<String> errorMessages; private final List<String> warningMessages; private final int id; /** * Used in {@link #connect()} and {@link #disconnect()} to be able to * restore the connection at the right index in the source's outgoing connections. */ private int outgoingConnectionIndex; private EipNode source; private AbstractNode target; private String conditionExpression, conditionName; private boolean consumeItf = true, consumeSrv = true, consumeEdpt = true; private String consumeOperation, consumeMep; /** * Constructor. * @param id * @param source * @param target */ public EipConnection( int id, EipNode source, AbstractNode target ) { this.id = id; this.source = source; this.target = target; this.listeners = new PropertyChangeSupport( this ); this.errorMessages = new ArrayList<String> (); this.warningMessages = new ArrayList<String>(); } /** * @param listener */ public void addPropertyChangeListener( PropertyChangeListener listener ) { this.listeners.addPropertyChangeListener( listener ); } /** * @param listener */ public void removePropertyChangeListener( PropertyChangeListener listener ) { this.listeners.removePropertyChangeListener( listener ); } /** * Sends a notification to refresh the connection. */ public void refreshConnection() { this.listeners.firePropertyChange( PROPERTY_CONNECTION_SOURCE, null, null ); } /** * @return the errorMessages (not modifiable and never null) * <p> * It cannot be modified because any modification should trigger a property change (propagate changes in MVC). * Use delegate methods to add or remove an element. * </p> */ public List<String> getErrorMessages() { return Collections.unmodifiableList( this.errorMessages ); } /** * Adds an error message for this element. * @param errorMessages a list of error messages (may be null) */ public void setErrorMessages( List<String> errorMessages ) { this.errorMessages.clear(); if( errorMessages != null ) this.errorMessages.addAll( errorMessages ); this.listeners.firePropertyChange( PROPERTY_ERROR, null, errorMessages ); } /** * Adds a warning message for this element. * @param warningMessages a list of warning messages (may be null) */ public void setWarningMessages( List<String> warningMessages ) { this.warningMessages.clear(); if( warningMessages != null ) this.warningMessages.addAll( warningMessages ); this.listeners.firePropertyChange( PROPERTY_ERROR, null, this.errorMessages ); } /** * @return the source */ public EipNode getSource() { return this.source; } /** * @param source the source to set * <p> * If the connection was already connected, then this connection is not * part of the outgoing connections of <i>source</i>. It will have to be * added explicitly or {@link #connect()} will have to be invoked again. * </p> */ public void setSource( EipNode source ) { this.source = source; } /** * @return the conditionName */ public String getConditionName() { return this.conditionName; } /** * @param conditionName the conditionName to set */ public void setConditionName( String conditionName ) { String oldValue = this.conditionName; this.conditionName = conditionName; this.listeners.firePropertyChange( PROPERTY_CONDITION_NAME, oldValue, this.conditionName ); } /** * @return the conditionExpression */ public String getConditionExpression() { return this.conditionExpression; } /** * @param conditionExpression the conditionExpression to set */ public void setConditionExpression( String conditionExpression ) { String oldValue = this.conditionExpression; this.conditionExpression = conditionExpression; this.listeners.firePropertyChange( PROPERTY_CONDITION_EXPRESSION, oldValue, this.conditionExpression ); } /** * @return the consumeItf */ public boolean isConsumeItf() { return this.consumeItf; } /** * @param consumeItf the consumeItf to set */ public void setConsumeItf( boolean consumeItf ) { boolean oldValue = this.consumeItf; this.consumeItf = consumeItf; this.listeners.firePropertyChange( PROPERTY_CONSUME_BY_ITF, oldValue, this.consumeItf ); } /** * @return the consumeSrv */ public boolean isConsumeSrv() { return isConsumeSrvPossible() ? this.consumeSrv : false; } /** * @param consumeSrv the consumeSrv to set */ public void setConsumeSrv( boolean consumeSrv ) { boolean oldValue = this.consumeSrv; this.consumeSrv = consumeSrv; this.listeners.firePropertyChange( PROPERTY_CONSUME_BY_SRV, oldValue, this.consumeSrv ); } /** * @return the consumeEdpt */ public boolean isConsumeEdpt() { return isConsumeEdptPossible() ? this.consumeEdpt : false; } /** * @return the consumeEdpt */ public boolean isConsumeEdptPossible() { return getTarget() != null && ! StringUtils.isEmpty( getTarget().getEndpointName()); } /** * @return the consumeEdpt */ public boolean isConsumeSrvPossible() { return getTarget() != null && ! StringUtils.isEmpty( getTarget().getServiceName()); } /** * @param consumeEdpt the consumeEdpt to set */ public void setConsumeEdpt( boolean consumeEdpt ) { boolean oldValue = this.consumeEdpt; this.consumeEdpt = consumeEdpt; this.listeners.firePropertyChange( PROPERTY_CONSUME_BY_EDPT, oldValue, this.consumeEdpt ); } /** * @return the consumeMep */ public String getConsumeMep() { return this.consumeMep; } /** * @param consumeMep the consumeMep to set */ public void setConsumeMep( String consumeMep ) { String oldValue = this.consumeMep; this.consumeMep = consumeMep; this.listeners.firePropertyChange( PROPERTY_CONSUMED_MEP, oldValue, this.consumeMep ); } /** * @return the consumeOperation */ public String getConsumeOperation() { return this.consumeOperation; } /** * @param consumeOperation the consumeOperation to set */ public void setConsumeOperation( String consumeOperation ) { String oldValue = this.consumeOperation; this.consumeOperation = consumeOperation; this.listeners.firePropertyChange( PROPERTY_CONSUMED_OPERATION, oldValue, this.consumeOperation ); } /** * @return the target */ public AbstractNode getTarget() { return this.target; } /** * @return the id */ public int getId() { return this.id; } /* * (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return this.id; } /* * (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals( Object obj ) { return obj instanceof EipConnection && ((EipConnection) obj).id == this.id; } /** * Adds this connection in the model. */ public void connect() { // Update the model if( this.alreadyConnected ) this.target.getEipChain().restoreConnection( this ); else { this.outgoingConnectionIndex = -1; this.alreadyConnected = true; this.target.getEipChain().simplyAddConnection( this ); } if( this.target != null ) this.target.setIncomingConnection( this ); if( this.source != null ) { if( this.outgoingConnectionIndex == -1 ) this.source.addOutgoingConnection( this ); else this.source.addOutgoingConnection( this, this.outgoingConnectionIndex ); } // If the target is an EIP, the consume operation may have to be updated if( this.target instanceof EipNode && StringUtils.isEmpty( this.consumeOperation )) setConsumeOperation( "{" + EipNode.DEFAULT_EIP_NS + "}anyOperation" ); } /** * Removes this connection from the model. */ public void disconnect() { if( this.target != null ) { this.target.getEipChain().removeConnection( this ); this.target.setIncomingConnection( null ); } if( this.source != null ) { this.outgoingConnectionIndex = this.source.getOutgoingConnections().indexOf( this ); this.target.getEipChain().removeConnection( this ); this.source.removeOutgoingConnection( this ); } } /** * Changes the source or the target of a connection. * @param sourceNode the source node * @param targetNode the target node */ public void reconnect( EipNode sourceNode, AbstractNode targetNode ) { if( sourceNode == null || targetNode == null || sourceNode == targetNode ) throw new IllegalArgumentException(); disconnect(); this.source = sourceNode; this.target = targetNode; connect(); } /** * @return true if this connection should define a condition, false otherwise */ public boolean shouldHaveCondition() { boolean result = false; if( this.source != null ) { if( this.source.getEipType() == EIPtype.ROUTER || this.source.getEipType() == EIPtype.DYNAMIC_ROUTER ) { int pos = this.source.getOutgoingConnections().indexOf( this ); int size = this.source.getOutgoingConnections().size(); result = pos != size - 1; } } return result; } public List<String> getWarningMessages() { return this.warningMessages; } }