/*
* JBoss, Home of Professional Open Source
* Copyright 2012, Red Hat Middleware LLC, and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.savara.protocol.internal.aggregator;
import java.util.logging.Logger;
import org.savara.protocol.internal.aggregator.GlobalProtocolUnit.Container;
import org.scribble.protocol.model.Activity;
import org.scribble.protocol.model.Block;
import org.scribble.protocol.model.Choice;
import org.scribble.protocol.model.Interaction;
import org.scribble.protocol.model.Introduces;
import org.scribble.protocol.model.ProtocolModel;
import org.scribble.protocol.model.Repeat;
import org.scribble.protocol.model.Role;
import org.scribble.protocol.util.RoleUtil;
public class LocalProtocolUnit {
private static final Logger LOG=Logger.getLogger(LocalProtocolUnit.class.getName());
private ActivityCursor _cursor=null;
public LocalProtocolUnit(ProtocolModel model) {
_cursor = new ActivityCursor(model.getProtocol().getLocatedRole(),
model.getProtocol().getBlock());
}
public ActivityCursor getRootCursor() {
return(_cursor);
}
public ActivityCursor getSendingCursor() {
return(_cursor.getSendingCursor());
}
public ActivityCursor getActivityWithClientCursor(Role role) {
return(_cursor.getActivityWithClientCursor(role));
}
public ActivityCursor findReceivingCursor(Activity send) {
return(_cursor.findReceivingCursor(send));
}
public ActivityCursor getIndividualCursor() {
return(_cursor.getIndividualCursor());
}
public ActivityCursor getRepetitionCursor() {
return(_cursor.getRepetitionCursor());
}
public class ActivityCursor {
private Role _role=null;
private Block _block=null;
private int _position=0;
private Container _container=null;
private ActivityCursor _parent=null;
private java.util.List<ActivityCursor> _cursors=new java.util.Vector<ActivityCursor>();
public ActivityCursor(Role r, Block b) {
_role = r;
_block = b;
}
public ActivityCursor(ActivityCursor parent, Role r, Block b) {
this(r, b);
_parent = parent;
}
public Role getRole() {
return (_role);
}
public ActivityCursor createCursor(Block b) {
ActivityCursor ret=new ActivityCursor(this, _role, b);
_cursors.add(ret);
return(ret);
}
public Container getContainer() {
return(_container);
}
public ActivityCursor getParent() {
return(_parent);
}
public void setContainer(Container c) {
_container = c;
}
private ActivityCursor getSendingCursor() {
ActivityCursor ret=null;
if (_cursors.size() > 0) {
for (ActivityCursor cur : _cursors) {
ret = cur.getSendingCursor();
if (ret != null) {
break;
}
}
} else if (isSendingAction()) {
ret = this;
}
return(ret);
}
private ActivityCursor getActivityWithClientCursor(Role role) {
ActivityCursor ret=null;
if (_cursors.size() > 0) {
for (ActivityCursor cur : _cursors) {
ret = cur.getActivityWithClientCursor(role);
if (ret != null) {
break;
}
}
} else if (isActivityWithClientAction(role)) {
ret = this;
}
return(ret);
}
private ActivityCursor getIndividualCursor() {
ActivityCursor ret=null;
if (_cursors.size() > 0) {
for (ActivityCursor cur : _cursors) {
ret = cur.getIndividualCursor();
if (ret != null) {
break;
}
}
} else if (isIndividualAction()) {
ret = this;
}
return(ret);
}
private ActivityCursor getRepetitionCursor() {
ActivityCursor ret=null;
if (_cursors.size() > 0) {
for (ActivityCursor cur : _cursors) {
ret = cur.getRepetitionCursor();
if (ret != null) {
break;
}
}
} else if (isRepetitionAction()) {
ret = this;
}
return(ret);
}
protected boolean isSendingAction() {
boolean ret=false;
Activity act=peek();
if (act instanceof Interaction) {
ret = ((Interaction)act).getFromRole() == null;
/*
} else if (act instanceof Choice) {
ret = ((Choice)act).getRole() != null &&
((Choice)act).getRole().equals(_role);
*/
}
return(ret);
}
protected boolean isActivityWithClientAction(Role role) {
boolean ret=false;
Activity act=peek();
if (act instanceof Interaction) {
ret = (((Interaction)act).getFromRole() != null
&& ((Interaction)act).getFromRole().equals(role)) ||
((Interaction)act).getToRoles().contains(role);
}
LOG.finest("Is activity with client action ("+act
+") for role="+role+"? "+ret);
return(ret);
}
protected boolean isIndividualAction() {
boolean ret=false;
Activity act=peek();
if (act instanceof Introduces) {
ret = true;
} else if (act instanceof Choice) {
//Choice choice=(Choice)act;
// Ok to treat as individual action if the choice
// is not associated with the decision maker
// NOTE: Currently decision makers (and matching receive
// choices) are handled as matched actions, but
// in the future may want to simplify so that both
// are treated as individual actions? Benefit of
// current approach is that it may delay establishing
// the global choice until the decision maker has
// a matching receive choice.
//ret = (choice.getRole() == null ||
// !choice.getRole().equals(_role));
ret = true;
}
return(ret);
}
protected boolean isRepetitionAction() {
boolean ret=false;
Activity act=peek();
if (act instanceof Repeat) {
ret = true;
}
return(ret);
}
/**
* This method determines the list of roles involved in
* the repetition construct.
*
* @return The roles
*/
public java.util.Set<Role> getRepetitionRoles() {
java.util.Set<Role> ret=null;
Activity act=peek();
if (act != null && isRepetitionAction()) {
ret = RoleUtil.getUsedRoles(act);
} else {
ret = new java.util.HashSet<Role>();
}
return (ret);
}
public Activity peek() {
return(_position < _block.size() ? _block.get(_position) : null);
}
public boolean next() {
_position++;
boolean ret=_position < _block.size();
if (!ret) {
delete();
}
return(ret);
}
protected void delete() {
if (_cursors.size() == 0 && _parent != null) {
_parent.deleteCursor(this);
}
}
protected void deleteCursor(ActivityCursor cursor) {
_cursors.remove(cursor);
// Check if should propagate deletion
if (_position >= _block.size()) {
delete();
}
}
public ActivityCursor findReceivingCursor(Activity send) {
ActivityCursor ret=null;
if (_cursors.size() > 0) {
for (ActivityCursor cur : _cursors) {
ret = cur.findReceivingCursor(send);
if (ret != null) {
break;
}
}
} else if (getReceiveAction(send) != null) {
ret = this;
}
return(ret);
}
public Activity getReceiveAction(Activity send) {
Activity ret=null;
Activity cur=peek();
if (cur instanceof Interaction && send instanceof Interaction) {
Interaction receive=(Interaction)cur;
if (((Interaction)send).getMessageSignature().equals(receive.getMessageSignature()) &&
receive.getFromRole() != null) {
ret = receive;
}
} else if (cur instanceof Choice && send instanceof Choice) {
Choice receive=(Choice)cur;
if (((Choice)send).getRole().equals(receive.getRole())) {
ret = receive;
}
} else {
// TODO: Log error
}
return(ret);
}
}
}