/*
* Copyright (c) 2006 Stiftung Deutsches Elektronen-Synchroton,
* Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
*
* THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS.
* WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE
* IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR
* CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
* NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
* DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
* THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION,
* USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS
* PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY
* AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM
*/
/**
*
*/
package org.epics.css.dal.simulation;
import java.beans.PropertyChangeEvent;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import org.csstudio.dal.DataExchangeException;
import org.csstudio.dal.DynamicValueState;
import org.csstudio.dal.RemoteException;
import org.csstudio.dal.Request;
import org.csstudio.dal.ResponseListener;
import org.csstudio.dal.context.ConnectionState;
import org.csstudio.dal.impl.RequestImpl;
import org.csstudio.dal.impl.ResponseImpl;
import org.csstudio.dal.proxy.AbstractPropertyProxyImpl;
import org.csstudio.dal.proxy.DirectoryProxy;
import org.csstudio.dal.proxy.MonitorProxy;
import org.csstudio.dal.proxy.PropertyProxy;
import org.csstudio.dal.proxy.SyncPropertyProxy;
import org.epics.css.dal.simulation.data.DataGeneratorInfo;
/**
* Simulations implementations of proxy.
*
* @author ikriznar
*
*/
public class PropertyProxyImpl<T> extends AbstractPropertyProxyImpl<T,SimulatorPlug,MonitorProxyImpl<T>> implements PropertyProxy<T,SimulatorPlug>, SyncPropertyProxy<T,SimulatorPlug>, DirectoryProxy<SimulatorPlug>{
protected ValueProvider<T> valueProvider = new MemoryValueProvider<T>();
protected boolean isSettable = true;
private long refreshRate = 1000;
/**
* Creates new instance.
* @param name
*/
public PropertyProxyImpl(String name, SimulatorPlug plug, Class<T> type){
this(name, plug, (Long)SimulatorUtilities.getConfiguration(SimulatorUtilities.CONNECTION_DELAY),type);
}
/**
* Creates new instance.
* @param name
* @param connectDelay
*/
public PropertyProxyImpl(String name, SimulatorPlug plug, long connectDelay, Class<T> type){
super(name,plug);
setConnectionState(ConnectionState.READY);
DataGeneratorInfo info = DataGeneratorInfo.getInfo(name);
refreshRate = info.getRefreshRate(name);
setValueProvider(info.getDataGeneratorFactory().createGenerator(type, info.getOptions(name)));
delayedConnect(connectDelay);
updateConditionWith("", DynamicValueState.HAS_METADATA);
}
public void delayedConnect(long timeout){
setConnectionState(ConnectionState.CONNECTING);
if (timeout > 0) {
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run(){
if (getConnectionState()==ConnectionState.CONNECTING)
setConnectionState(ConnectionState.CONNECTED);
}
}, timeout);
}
else
setConnectionState(ConnectionState.CONNECTED);
}
/* (non-Javadoc)
* @see org.epics.css.dal.proxy.PropertyProxy#getValueAsync(org.epics.css.dal.ResponseListener)
*/
@Override
public Request<T> getValueAsync(ResponseListener<T> callback) throws DataExchangeException{
if (getConnectionState() != ConnectionState.CONNECTED)
throw new DataExchangeException(this, "Proxy not connected");
RequestImpl<T> r = new RequestImpl<T>(this, callback);
r.addResponse(new ResponseImpl<T>(this, r, valueProvider.get(), "value", true, null, getCondition(), null, true));
return r;
}
/* (non-Javadoc)
* @see org.epics.css.dal.proxy.PropertyProxy#setValueAsync(T, org.epics.css.dal.ResponseListener)
*/
@Override
public Request<T> setValueAsync(T value, ResponseListener<T> callback) throws DataExchangeException{
if (getConnectionState() != ConnectionState.CONNECTED)
throw new DataExchangeException(this, "Proxy not connected");
setValueSync(value);
RequestImpl<T> r = new RequestImpl<T>(this, callback);
r.addResponse(new ResponseImpl<T>(this, r, value, "", true, null, getCondition(), null, true));
return r;
}
/* (non-Javadoc)
* @see org.epics.css.dal.proxy.PropertyProxy#isSettable()
*/
@Override
public boolean isSettable(){
return isSettable;
}
public void setSettable(boolean settable){
this.isSettable = settable;
}
/* (non-Javadoc)
* @see org.epics.css.dal.proxy.PropertyProxy#createMonitor(org.epics.css.dal.ResponseListener)
*/
@Override
public MonitorProxy createMonitor(ResponseListener<T> callback, Map<String,Object> param) throws RemoteException{
MonitorProxyImpl<T> m = new MonitorProxyImpl<T>(this, callback);
m.setTimerTrigger(refreshRate);
return m;
}
@Override
public void destroy(){
super.destroy();
if (connectionStateMachine.isConnected())
setConnectionState(ConnectionState.DISCONNECTING);
if (connectionStateMachine.getConnectionState()==ConnectionState.DISCONNECTING)
setConnectionState(ConnectionState.DISCONNECTED);
setConnectionState(ConnectionState.DESTROYED);
}
/**
* @see DirectoryProxy#getCharacteristicNames()
*/
@Override
public String[] getCharacteristicNames() throws DataExchangeException{
return SimulatorUtilities.getCharacteristicNames(this);
}
@Override
protected Object processCharacteristicBeforeCache(Object value, String characteristicName) {
return SimulatorUtilities.getCharacteristic(characteristicName, this);
}
@Override
protected Object processCharacteristicAfterCache(Object value, String characteristicName) {
return value;
}
@Override
public T getValueSync() throws DataExchangeException{
if (getConnectionState() != ConnectionState.CONNECTED)
throw new DataExchangeException(this, "Proxy not connected");
return valueProvider.get();
}
@Override
public void setValueSync(T value) throws DataExchangeException{
if (getConnectionState() != ConnectionState.CONNECTED)
throw new DataExchangeException(this, "Proxy not connected");
valueProvider.set(value);
MonitorProxyImpl<T>[] m = getMonitors().toArray(new MonitorProxyImpl[getMonitors().size()]);
for (int i = 0; i < m.length; i++)
m[i].fireValueChange();
}
/**
* @return Returns the valueProvder.
*/
public ValueProvider<T> getValueProvider(){
return valueProvider;
}
/**
* @param valueProvder The valueProvder to set.
*/
public void setValueProvider(ValueProvider<T> valueProvder){
try {
valueProvder.set(this.valueProvider.get());
} catch (Exception e) {
}
this.valueProvider = valueProvder;
}
@Override
public void refresh(){
// Override in order to clean up cached values.
}
/**
* Simulate changes of connection state
* @param state Connection State
*/
public void simulateConnectionState(ConnectionState state){
setConnectionState(state);
}
public void simulateCharacteristicChange(String characteristicName, Object value) {
Object old= SimulatorUtilities.putCharacteristic(characteristicName, getUniqueName(), value);
fireCharacteristicsChanged(new PropertyChangeEvent(this,characteristicName,old,value));
}
@Override
protected String getRemoteHostInfo() {
return "local";
}
}