
org.tango.server.attribute.ReflectAttributeBehavior Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JTangoServer Show documentation
Show all versions of JTangoServer Show documentation
Library for Tango Server (ie. Tango Device) in Java
The newest version!
/**
* Copyright (C) : 2012
*
* Synchrotron Soleil
* L'Orme des merisiers
* Saint Aubin
* BP48
* 91192 GIF-SUR-YVETTE CEDEX
*
* This file is part of Tango.
*
* Tango 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.
*
* Tango 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 Tango. If not, see .
*/
package org.tango.server.attribute;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tango.DeviceState;
import org.tango.server.ExceptionMessages;
import org.tango.server.StateMachineBehavior;
import org.tango.utils.DevFailedUtils;
import fr.esrf.Tango.DevFailed;
import fr.esrf.Tango.DevState;
/**
* Behavior a Tango attribute using java reflection
*
* @author ABEILLE
*
*/
public final class ReflectAttributeBehavior implements IAttributeBehavior {
private final Logger logger = LoggerFactory.getLogger(ReflectAttributeBehavior.class);
private final AttributeConfiguration config;
private final Method getter;
private final Method setter;
private final Object businessObject;
/**
* Ctr
*
* @param config
* The attribute configuration
* @param businessObject
* The object that contains the attribute
* @param getter
* The method to read the attribute
* @param setter
* The method to write the attribute
*/
public ReflectAttributeBehavior(final AttributeConfiguration config, final Object businessObject,
final Method getter, final Method setter) {
this.businessObject = businessObject;
this.getter = getter;
this.setter = setter;
this.config = config;
}
@Override
public AttributeValue getValue() throws DevFailed {
final AttributeValue result;
Object value = null;
if (getter != null) {
try {
logger.debug("read attribute {} from method '{}'", config.getName(), getter);
value = getter.invoke(businessObject);
} catch (final IllegalArgumentException e) {
DevFailedUtils.throwDevFailed(e);
} catch (final IllegalAccessException e) {
DevFailedUtils.throwDevFailed(e);
} catch (final InvocationTargetException e) {
throwDevFailed(e);
}
}
result = buildAttributeValue(value);
return result;
}
private void throwDevFailed(final InvocationTargetException e) throws DevFailed {
if (e.getCause() instanceof DevFailed) {
throw (DevFailed) e.getCause();
} else {
DevFailedUtils.throwDevFailed(e.getCause());
}
}
private AttributeValue buildAttributeValue(final Object value) throws DevFailed {
AttributeValue result = null;
if (value == null) {
result = new AttributeValue(null);
} else if (value instanceof AttributeValue) {
result = (AttributeValue) value;
} else if (value instanceof DeviceState) {
final DeviceState state = (DeviceState) value;
result = new AttributeValue(state.getDevState());
} else if (value instanceof DeviceState[]) {
final DeviceState[] in = (DeviceState[]) value;
final DevState[] devStates = new DevState[in.length];
for (int i = 0; i < in.length; i++) {
devStates[i] = in[i].getDevState();
}
result = new AttributeValue(devStates);
} else if (value instanceof Enum) {
final Enum> enumValue = (Enum>) value;
result = new AttributeValue((short) enumValue.ordinal());
} else {
result = new AttributeValue(value);
}
return result;
}
@Override
public void setValue(final AttributeValue value) throws DevFailed {
if (setter != null && setter.getParameterTypes().length == 1) {
final Class> paramSetter = getParamSetter();
try {
if (paramSetter.equals(DeviceState.class)) {
setter.invoke(businessObject, DeviceState.getDeviceState((DevState) value.getValue()));
} else if (Enum.class.isAssignableFrom(paramSetter)) {
final short enumValue = (Short) value.getValue();
setter.invoke(businessObject, paramSetter.getEnumConstants()[enumValue]);
} else if (paramSetter.equals(DeviceState[].class)) {
final DevState[] states = (DevState[]) value.getValue();
final DeviceState[] devStates = new DeviceState[states.length];
for (int i = 0; i < devStates.length; i++) {
devStates[i] = DeviceState.getDeviceState(states[i]);
}
setter.invoke(businessObject, (Object) devStates);
} else {
final Class> input = getInputClass(value);
checkParamTypes(value, paramSetter, input);
setter.invoke(businessObject, value.getValue());
}
} catch (final IllegalArgumentException e) {
DevFailedUtils.throwDevFailed(e);
} catch (final IllegalAccessException e) {
DevFailedUtils.throwDevFailed(e);
} catch (final InvocationTargetException e) {
throwDevFailed(e);
}
}
}
private void checkParamTypes(final AttributeValue value, final Class> paramSetter, final Class> input)
throws DevFailed {
if (!paramSetter.isAssignableFrom(input)) {
DevFailedUtils.throwDevFailed(ExceptionMessages.ATTR_OPT_PROP,
"type mismatch, expected was " + setter.getParameterTypes()[0].getCanonicalName() + ", input is "
+ value.getValue().getClass().getCanonicalName());
}
}
private Class> getInputClass(final AttributeValue value) {
Class> input = value.getValue().getClass();
if (Number.class.isAssignableFrom(input) || Boolean.class.isAssignableFrom(input)) {
input = ClassUtils.wrapperToPrimitive(value.getValue().getClass());
}
return input;
}
private Class> getParamSetter() {
Class> paramSetter = setter.getParameterTypes()[0];
if (Number.class.isAssignableFrom(paramSetter) || Boolean.class.isAssignableFrom(paramSetter)) {
paramSetter = ClassUtils.wrapperToPrimitive(setter.getParameterTypes()[0]);
}
return paramSetter;
}
@Override
public AttributeConfiguration getConfiguration() {
return config;
}
@Override
public StateMachineBehavior getStateMachine() {
return null;
}
@Override
public String toString() {
final ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
builder.append("getter", getter);
builder.append("setter", setter);
return builder.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy