/*
* Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved.
*
* This file is part of the Jspresso framework.
*
* Jspresso is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Jspresso is distributed in the hope that it will be useful,
* but WITHOUT ANY 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
* along with Jspresso. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jspresso.framework.binding.remote;
import org.jspresso.framework.binding.basic.BasicValueConnector;
import org.jspresso.framework.state.remote.IRemoteStateOwner;
import org.jspresso.framework.state.remote.IRemoteStateValueMapper;
import org.jspresso.framework.state.remote.RemoteValueState;
import org.jspresso.framework.util.automation.IPermIdSource;
import org.jspresso.framework.util.remote.IRemotePeer;
/**
* The server peer of a remote value connector.
*
* @author Vincent Vandenschrick
*/
public class RemoteValueConnector extends BasicValueConnector implements
IRemotePeer, IRemoteStateOwner, IPermIdSource {
private String permId;
private final RemoteConnectorFactory connectorFactory;
private String guid;
private IRemoteStateValueMapper remoteStateValueMapper;
private RemoteValueState state;
/**
* Constructs a new {@code RemoteValueConnector} instance.
*
* @param id
* the connector id.
* @param connectorFactory
* the remote connector factory.
*/
public RemoteValueConnector(String id, RemoteConnectorFactory connectorFactory) {
super(id);
this.guid = connectorFactory.generateGUID();
this.connectorFactory = connectorFactory;
connectorFactory.register(this);
}
/**
* Returns the actual connector value.
* <p>
* {@inheritDoc}
*/
@Override
public Object actualValue() {
return getConnectorValue();
}
/**
* {@inheritDoc}
*/
@Override
public RemoteValueConnector clone() {
return clone(getId());
}
/**
* {@inheritDoc}
*/
@Override
public RemoteValueConnector clone(String newConnectorId) {
RemoteValueConnector clonedConnector = (RemoteValueConnector) super
.clone(newConnectorId);
clonedConnector.guid = connectorFactory.generateGUID();
clonedConnector.state = null;
connectorFactory.attachListeners(clonedConnector);
connectorFactory.register(clonedConnector);
return clonedConnector;
}
/**
* Gets the permId.
*
* @return the permId.
*/
@Override
public String getPermId() {
if (permId != null) {
return permId;
}
return getId();
}
/**
* Gets the guid.
*
* @return the guid.
*/
@Override
public String getGuid() {
return guid;
}
/**
* {@inheritDoc}
*/
@Override
public RemoteValueState getState() {
if (state == null) {
state = connectorFactory.createRemoteValueState(getGuid(), getPermId());
}
state.setValue(getValueForState());
state.setReadable(isReadable());
state.setWritable(isWritable());
return state;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isWritable() {
return (getModelConnector() != null) && super.isWritable();
}
/**
* Sets the permanent identifier to this application element. Permanent
* identifiers are used by different framework parts, like dynamic security or
* record/replay controllers to uniquely identify an application element.
* Permanent identifiers are generated by the SJS build based on the element
* id but must be explicitly set if Spring XML is used.
*
* @param permId
* the permId to set.
*/
@Override
public void setPermId(String permId) {
this.permId = permId;
}
/**
* Sets the remoteStateValueMapper.
*
* @param remoteStateValueMapper
* the remoteStateValueMapper to set.
*/
@Override
public void setRemoteStateValueMapper(
IRemoteStateValueMapper remoteStateValueMapper) {
this.remoteStateValueMapper = remoteStateValueMapper;
}
/**
* Gets the remoteStateValueMapper.
*
* @return the remoteStateValueMapper.
*/
protected IRemoteStateValueMapper getRemoteStateValueMapper() {
return remoteStateValueMapper;
}
/**
* Gets the value that has to be set to the remote state when updating it. It
* defaults to the connector value but the developer is given a chance here
* to mutate the actual object returned. This allows for changing the type of
* objects actually exchanged with the remote frontend peer.
*
* @return the value that has to be set to the remote state when updating it.
*/
protected Object getValueForState() {
Object valueForState = getConnectorValue();
if (getRemoteStateValueMapper() != null) {
valueForState = getRemoteStateValueMapper().getValueForState(state, valueForState);
}
return valueForState;
}
/**
* Sets the value that has to be set from the remote state when updating it.
* It defaults to the incoming value but the developer is given a chance here
* to mutate the actual object that comes in. This allows for changing the
* type of objects actually exchanged with the remote frontend peer.
*
* @param stateValue
* the incoming value.
*/
@Override
public void setValueFromState(Object stateValue) {
Object valueFromState;
if (getRemoteStateValueMapper() != null) {
valueFromState = getRemoteStateValueMapper()
.getValueFromState(state, stateValue);
} else {
valueFromState = stateValue;
}
setConnectorValue(valueFromState);
}
}