/*
* 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.csstudio.sds.internal.connection;
import java.util.Map;
import org.csstudio.dal.simple.ConnectionParameters;
import org.csstudio.dal.simple.RemoteInfo;
import org.csstudio.dal.simple.SimpleDALBroker;
import org.csstudio.domain.common.strings.Strings;
import org.csstudio.platform.model.pvs.IProcessVariableAddress;
import org.csstudio.platform.model.pvs.ValueType;
import org.csstudio.sds.SdsPlugin;
import org.csstudio.sds.eventhandling.AbstractBehavior;
import org.csstudio.sds.internal.model.logic.RuleEngine;
import org.csstudio.sds.internal.rules.ParameterDescriptor;
import org.csstudio.sds.internal.rules.RuleDescriptor;
import org.csstudio.sds.internal.rules.RuleService;
import org.csstudio.sds.model.AbstractWidgetModel;
import org.csstudio.sds.model.DynamicsDescriptor;
import org.csstudio.sds.model.WidgetProperty;
/**
* Utility class that provides facilities to connect SDS widgets to a control
* system using {@link SimpleDALBroker}.
*
* @author swende
*
*/
public final class ConnectionUtilNew {
public static void connectToWidgetManagementApi(
final AbstractWidgetModel widgetModel) {
widgetModel.getPermissionID();
}
/**
* Connects the specified widget model to the control system. Thereby the
* necessary listeners will be connected to control system channels and/or
* widget properties.
*
* @param widgetModel
* the widget model
* @param refreshRate
* the refresh rate
*
*/
public static void connectDynamizedProperties(
final WidgetProperty property, final Map<String, String> aliases,
final boolean writeAccessAllowed, final IListenerRegistry registry,
final SimpleDALBroker broker) {
// read the dynamics descriptor
final DynamicsDescriptor dynamicsDescriptor = property
.getDynamicsDescriptor();
// a dynamics descriptor must not exist
if (dynamicsDescriptor != null) {
// get all input references
final ParameterDescriptor[] parameters = dynamicsDescriptor.getInputChannels();
// .. connect input channels
if (parameters.length > 0) {
// .. find the rule
final String ruleId = dynamicsDescriptor.getRuleId();
final RuleDescriptor ruleDescriptor = RuleService.getInstance().getRuleDescriptor(ruleId);
if (ruleDescriptor != null) {
// .. create the rule engine
final RuleEngine ruleEngine = new RuleEngine(ruleDescriptor.getRule(), parameters);
for (final ParameterDescriptor p : parameters) {
final IProcessVariableAddress processVariable = p.getPv(aliases);
if (processVariable != null) {
// .. connect to control system
final ValueType valueType = determineValueType(property, processVariable);
ConnectionParameters cparam;
// TODO 30.10.2010 (hrickens) workaround until Enum data type is introduced
switch (valueType) {
case STRING:
cparam = new ConnectionParameters(translateWithoutCharacteristic(processVariable), String.class);
break;
case LONG:
cparam = new ConnectionParameters(translateWithoutCharacteristic(processVariable), Long.class);
break;
case DOUBLE:
cparam = new ConnectionParameters(translateWithoutCharacteristic(processVariable), Double.class);
break;
default:
cparam = new ConnectionParameters(translateWithoutCharacteristic(processVariable));
break;
}
final ChannelInputProcessor processor = new ChannelInputProcessor(
p,
ruleEngine,
property,
dynamicsDescriptor
.getConnectionStateDependentPropertyValues(),
dynamicsDescriptor
.getConditionStateDependentPropertyValues());
final String characteristic = processVariable
.getCharacteristic();
final SinglePropertyReadConnector connector = new SinglePropertyReadConnector(
processor, valueType, characteristic);
registry.register(cparam, connector);
}
}
}
}
// .. connect output channels
final ParameterDescriptor parameter = dynamicsDescriptor
.getOutputChannel();
if ((parameter != null) && writeAccessAllowed) {
final IProcessVariableAddress processVariable = parameter
.getPv(aliases);
if (processVariable != null) {
final ValueType type = determineValueType(property,
processVariable);
final SinglePropertyWriteConnector connector = new SinglePropertyWriteConnector(
processVariable, type, broker);
registry.register(property, connector);
}
}
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void connectToBehavior(final AbstractWidgetModel widget,
final IListenerRegistry registry) {
final String behaviorId = widget
.getBehaviorProperty(AbstractWidgetModel.PROP_BEHAVIOR);
if ((behaviorId != null) && (behaviorId.length() > 0)) {
final AbstractBehavior behavior = SdsPlugin.getDefault()
.getBehaviourService().getBehavior(behaviorId,
widget.getTypeID());
final IProcessVariableAddress mainPv = widget.getMainPvAdress();
if ((behavior != null) && (mainPv != null)) {
// .. let the behavior initialize the widget before any
// connections are opened
behavior.initializeWidget(widget);
final Class javaType = widget.getJavaType();
final ConnectionParameters connectionParameters = new ConnectionParameters(
new RemoteInfo(RemoteInfo.DAL_TYPE_PREFIX + "EPICS",
mainPv.getProperty(), null, null), javaType);
if (connectionParameters != null) {
if (behavior != null) {
final BehaviorConnector behaviorConnector = new BehaviorConnector(
widget, connectionParameters, behavior);
// .. let the behavior initialize the widget before any
// connections are opened
// hrickens (23.07.2010): move up to initializeWidget before connect.
// behavior.initializeWidget(widget);
// .. connect to the control system to receive dynamic
// values and meta data
registry.register(connectionParameters,
behaviorConnector);
// .. connect to the widget to receive manual changes
// and forward them to the control system
final String[] settablePropertyIds = behavior
.getSettablePropertyIds();
for (final String id : settablePropertyIds) {
widget.addPropertyChangeListener(id,
behaviorConnector);
}
}
}
}
}
}
/**
* Determines which {@link ValueType} is implied by the given
* {@link WidgetProperty} and {@link IProcessVariableAddress}.
*
* @param property
* The {@link WidgetProperty}
* @param processVariable
* The {@link IProcessVariableAddress}
* @return The {@link ValueType} to use
*/
private static ValueType determineValueType(final WidgetProperty property,
final IProcessVariableAddress processVariable) {
// 1. choice, is there a type hint directly on
// the pv ?
ValueType type = processVariable.getValueTypeHint();
// TODO (jhatje): remove if patch in jca lib works
// // 2 nd choise from rule
// /*
// * XXX hrickens 2010.11.10: ad as workarround for the DAL crash with
// * JNI. DAL crashed in case of wrong pv request. E.g.: get a String Pv
// * as Double.
// */
// if (type == null) {
// if (isStringRecord(processVariable)) {
// type = ValueType.STRING;
// }
// }
// 3nd choice
if (type == null) {
// take the type hint, provided
// by the widget
// property
type = property.getPropertyType().getTypeHint();
}
// 4rd choice, take double
if (type == null) {
type = ValueType.DOUBLE;
}
return type;
}
// TODO (jhatje): remove if patch in jca lib works
// private static boolean isStringRecord(IProcessVariableAddress processVariable) {
// ArrayList<String> recordTails = SdsPlugin.getDefault().getRecordTails();
// for (String recTail : recordTails) {
// if (processVariable.getProperty().endsWith(recTail)) {
// return true;
// }
// }
// ArrayList<String> recordTailsRegExp = SdsPlugin.getDefault().getRecordTailsRegExp();
// for (String recTailRegExp : recordTailsRegExp) {
// if (processVariable.getProperty().matches(recTailRegExp)) {
// return true;
// }
// }
// return false;
// }
static final RemoteInfo translateWithoutCharacteristic(final IProcessVariableAddress pv) {
String cs = "";
final String responsibleDalPlugId = pv.getControlSystem().getResponsibleDalPlugId();
if((responsibleDalPlugId!=null) && !Strings.isBlank(responsibleDalPlugId)) {
cs = RemoteInfo.DAL_TYPE_PREFIX
+ responsibleDalPlugId;
}
final String property = pv.getProperty();
return new RemoteInfo(cs, property, null, null);
}
}