package com.yahoo.dtf.share;
import java.util.concurrent.Semaphore;
import com.yahoo.dtf.actions.Action;
import com.yahoo.dtf.actions.flowcontrol.Sequence;
import com.yahoo.dtf.actions.share.Share_set;
import com.yahoo.dtf.exception.DTFException;
import com.yahoo.dtf.exception.ParseException;
import com.yahoo.dtf.logger.DTFLogger;
public abstract class Share {
private static DTFLogger _logger = DTFLogger.getLogger(Share.class);
private static Action DONOTHING = new Sequence();
private String _id = null;
private String _type = null;
private String _cid = null;
private Semaphore _semaphore = null;
public Share(String type, String id) throws DTFException {
_id = id;
_type = type;
_cid = Action.getLocalID();
_semaphore = new Semaphore(0);
}
public void setCid(String cid) { _cid = cid; }
public boolean isLocal() throws ParseException {
// localid is null when you haven't connected to the controller
return (Action.getLocalID() == null || Action.getLocalID().equals(_cid));
}
/**
* Set the action to the share and keep it till the getAction has been
* called.
*
* @param action
* @throws DTFException
*/
public abstract void setAction(Action action) throws DTFException;
/**
*
* @return
* @throws DTFException
*/
public abstract Action getAction() throws DTFException;
/**
*
* @param action
* @throws DTFException
*/
public void set(Action action) throws DTFException {
/*
* This duplication allows us to replace any properties that are
* necessary right now at set time where those properties would exist.
*
* Its costly to do this but there's really no other easy way of making
* sure that when we set some Actions for someone else to get that we
* have resolved all of the properties of those actions and have a copy
* of them that is thread safe.
*/
action = action.duplicate();
if ( !isLocal() ) {
if ( _logger.isDebugEnabled() )
_logger.debug("Setting share [" + getId() + "]");
Share_set ss = new Share_set();
ss.setId(getId());
ss.addAction(action);
Action.getComm().sendActionToCaller(_cid, ss).execute();
} else {
setAction(action);
_semaphore.release();
}
}
/**
*
* @return
* @throws DTFException
*/
public Action get(boolean blocking) throws DTFException {
if ( !isLocal() ) {
if ( _logger.isDebugEnabled() )
_logger.debug("Getting data from share [" + getId() +
"] on [" + _cid + "] ");
SharePointGet spw = new SharePointGet();
spw.setId(getId());
spw.setBlocking(""+blocking);
Action.getState().enableReplace();
return Action.getComm().sendActionToCaller(_cid, spw);
} else {
if ( blocking ) {
try {
_semaphore.acquire();
} catch (InterruptedException e) {
throw new DTFException("Unable to wait for action.");
}
return getAction();
} else {
return getAction();
}
}
}
/**
* This method will release all currently waiting threads on this share
* because the share has been destroyed and there is no reason to wait on
* a share_set to be done at all.
*/
public void releaseAll() {
_semaphore.release(Integer.MAX_VALUE);
}
public void setType(String type) { _type = type; }
public String getType() { return _type; }
public void setId(String id) { _id = id; }
public String getId() { return _id; }
}