All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tango.server.servant.AttributeGetterSetter Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show 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.servant;

import fr.esrf.Tango.*;
import net.sf.ehcache.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.ext.XLogger;
import org.slf4j.ext.XLoggerFactory;
import org.tango.DeviceState;
import org.tango.server.ExceptionMessages;
import org.tango.server.InvocationContext;
import org.tango.server.InvocationContext.CallType;
import org.tango.server.InvocationContext.ContextType;
import org.tango.server.ServerManager;
import org.tango.server.attribute.AttributeImpl;
import org.tango.server.attribute.AttributeValue;
import org.tango.server.attribute.ForwardedAttribute;
import org.tango.server.cache.PollingManager;
import org.tango.server.device.AroundInvokeImpl;
import org.tango.server.device.DeviceLocker;
import org.tango.server.device.StateImpl;
import org.tango.server.idl.CleverAnyAttribute;
import org.tango.server.idl.CleverAttrValUnion;
import org.tango.server.idl.TangoIDLAttributeUtil;
import org.tango.utils.DevFailedUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public final class AttributeGetterSetter {

    public static final String DOES_NOT_EXIST = " does not exist";
    private static final String ATTRIBUTE = "Attribute ";
    private static final XLogger XLOGGER = XLoggerFactory.getXLogger(AttributeGetterSetter.class);
    private static final Logger LOGGER = LoggerFactory.getLogger(AttributeGetterSetter.class);

    private AttributeGetterSetter() {

    }

    public static AttributeImpl getAttribute(final String name, final List attributeList)
            throws DevFailed {
        AttributeImpl result = null;
        for (final AttributeImpl attribute : attributeList) {
            if (attribute.getName().equalsIgnoreCase(name)) {
                result = attribute;
                break;
            }
        }
        if (result == null) {
            DevFailedUtils.throwDevFailed(ExceptionMessages.ATTR_NOT_FOUND, name + DOES_NOT_EXIST);
        }
        return result;
    }

    static void setAttributeValue4(final AttributeValue_4[] values, final List attributeList,
            final StateImpl stateImpl, final AroundInvokeImpl aroundInvoke, final ClntIdent clientID)
            throws MultiDevFailed {
        XLOGGER.entry();
        final List errors = new ArrayList();
        int i = 0;
        for (final AttributeValue_4 value4 : values) {
            final String name = value4.name;
            try {
                final AttributeImpl att = getAttribute(name, attributeList);
                // Call the always executed method
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_WRITE_ATTRIBUTE, CallType.UNKNOWN,
                        clientID, name));

                // Check if the attribute is allowed
                final DevState s = stateImpl.updateState();
                if (!att.isAllowed(DeviceState.getDeviceState(s))) {
                    DevFailedUtils.throwDevFailed(ExceptionMessages.COMMAND_NOT_ALLOWED, ATTRIBUTE + att.getName()
                            + " not allowed when the device is in " + DeviceState.toString(s));
                }
                final Object obj = CleverAttrValUnion.get(value4.value, att.getFormat());
                final AttributeValue attrValue = new AttributeValue(obj, value4.quality, value4.w_dim.dim_x,
                        value4.w_dim.dim_y);
                synchronized (att) {
                    att.setValue(attrValue);
                }
                // state machine
                stateImpl.stateMachine(att.getEndState());
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_WRITE_ATTRIBUTE, CallType.UNKNOWN,
                        clientID, name));
            } catch (final DevFailed e) {
                errors.add(new NamedDevError(name, i, e.errors));
            }
            i++;
        }
        if (!errors.isEmpty()) {
            throw new MultiDevFailed(errors.toArray(new NamedDevError[errors.size()]));
        }
        XLOGGER.exit();
    }

    static void setAttributeValue(final fr.esrf.Tango.AttributeValue[] values, final List attributeList,
            final StateImpl stateImpl, final AroundInvokeImpl aroundInvoke, final ClntIdent clientID) throws DevFailed {
        XLOGGER.entry();

        for (final fr.esrf.Tango.AttributeValue value3 : values) {
            final String name = value3.name;
            final AttributeImpl att = getAttribute(name, attributeList);
            if (!att.getFormat().equals(AttrDataFormat.SCALAR)) {
                DevFailedUtils.throwDevFailed("write only supported for SCALAR attributes");
            }
            // Call the always executed method
            aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_WRITE_ATTRIBUTE, CallType.UNKNOWN,
                    clientID, name));

            // Check if the attribute is allowed
            final DevState s = stateImpl.updateState();
            if (!att.isAllowed(DeviceState.getDeviceState(s))) {
                DevFailedUtils.throwDevFailed(ExceptionMessages.COMMAND_NOT_ALLOWED, ATTRIBUTE + att.getName()
                        + " not allowed when the device is in " + DeviceState.toString(s));
            }
            final Object obj = CleverAnyAttribute.get(value3.value, att.getTangoType(), att.getFormat());
            final AttributeValue attrValue = new AttributeValue(obj, value3.quality);
            synchronized (att) {
                att.setValue(attrValue);
            }
            // state machine
            stateImpl.stateMachine(att.getEndState());
            aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_WRITE_ATTRIBUTE, CallType.UNKNOWN,
                    clientID, name));
        }
        XLOGGER.exit();
    }

    static AttributeValue_5[] getAttributesValues5(final String deviceName, final String[] names,
            final PollingManager cacheManager, final List attributeList,
            final AroundInvokeImpl aroundInvoke, final DevSource source, final DeviceLocker locker,
            final ClntIdent clientID) throws DevFailed {
        // final Profiler profiler = new Profiler("get value time");
        final boolean fromCache = isFromCache(source);
        final CallType callType = CallType.getFromDevSource(source);
        final AttributeValue_5[] back = new AttributeValue_5[names.length];
        // profiler.start(Arrays.toString(names));
        // sort attributes with cache
        final Map cacheAttributes = new HashMap();
        final Map notCacheAttributes = new HashMap();
        for (int i = 0; i < names.length; i++) {
            AttributeImpl att = null;
            try {
                att = getAttribute(names[i], attributeList);
                if (source.equals(DevSource.DEV) && att.isPolled() && att.getPollingPeriod() == 0) {
                    // attribute is polled, so throw exception except
                    back[i] = TangoIDLAttributeUtil.toAttributeValue5Error(
                            names[i],
                            AttrDataFormat.FMT_UNKNOWN,
                            0,
                            DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_NOT_ALLOWED, ATTRIBUTE + names[i]
                                    + " value is available only by CACHE"));
                } else if (!deviceName.equalsIgnoreCase(ServerManager.getInstance().getAdminDeviceName())
                        && source.equals(DevSource.CACHE) && !att.isPolled()) {
                    // attribute is not polled, so throw exception except for admin device
                    back[i] = TangoIDLAttributeUtil.toAttributeValue5Error(
                            names[i],
                            AttrDataFormat.FMT_UNKNOWN,
                            0,
                            DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_NOT_POLLED, ATTRIBUTE + names[i]
                                    + " not polled"));
                } else if (att.isPolled() && fromCache) {
                    cacheAttributes.put(i, att);
                } else {
                    notCacheAttributes.put(i, att);
                }
            } catch (final DevFailed e) {
                back[i] = TangoIDLAttributeUtil.toAttributeValue5Error(names[i], AttrDataFormat.FMT_UNKNOWN, 0, e);
            }
        }

        // get value from cache
        for (final Entry attribute : cacheAttributes.entrySet()) {
            final AttributeImpl att = attribute.getValue();
            final int i = attribute.getKey();
            try {
                LOGGER.debug("read from CACHE {}", att.getName());
                // aroundInvoke
                // .aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTE, callType, att.getName()));
                // profiler.start("get cache");
                final AttributeValue readValue = cacheManager.getAttributeCacheElement(att);
                // profiler.start("to idl 5");
                if (readValue == null) {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue5Error(names[i], att.getFormat(),
                            att.getTangoType(),
                            DevFailedUtils.newDevFailed("CACHE_ERROR", names[i] + " not available from cache"));
                } else {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue5(att, readValue, att.getWriteValue());
                }
                // profiler.stop().print();
            } catch (final CacheException e) {
                if (e.getCause() instanceof DevFailed) {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue5Error(names[i], AttrDataFormat.FMT_UNKNOWN, 0,
                            (DevFailed) e.getCause());
                }
            }
            // aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTE, callType,
            // att.getName()));
        }
        // get attributes values
        if (!notCacheAttributes.isEmpty()) {
            final Object lock = locker.getAttributeLock();
            // lock if necessary
            synchronized (lock != null ? lock : new Object()) {
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTES, callType, clientID,
                        names));
                for (final Entry attribute : notCacheAttributes.entrySet()) {
                    final AttributeImpl att = attribute.getValue();
                    final int i = attribute.getKey();
                    LOGGER.debug("read from DEVICE {} ", att.getName());
                    aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTE, callType, clientID,
                            att.getName()));
                    try {

                        synchronized (att) {
                            if (att.getBehavior() instanceof ForwardedAttribute) {
                                // special case for fwd attribute where we retrieve directly a AttributeValue_5
                                final ForwardedAttribute fwdAttr = (ForwardedAttribute) att.getBehavior();
                                back[i] = fwdAttr.getValue5();
                            } else {
                                att.updateValue();
                                back[i] = TangoIDLAttributeUtil.toAttributeValue5(att, att.getReadValue(),
                                        att.getWriteValue());
                            }

                        }
                    } catch (final DevFailed e) {
                        back[i] = TangoIDLAttributeUtil.toAttributeValue5Error(names[i], att.getFormat(),
                                att.getTangoType(), e);
                    }
                    aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTE, callType,
                            clientID, att.getName()));
                } // for
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTES, callType, clientID,
                        names));
            } // synchronized
        }

        return back;
    }

    private static boolean isFromCache(final DevSource source) {
        boolean fromCache = false;
        if (source.equals(DevSource.CACHE) || source.equals(DevSource.CACHE_DEV)) {
            fromCache = true;
        }
        return fromCache;
    }

    static AttributeValue_4[] getAttributesValues4(final String deviceName, final String[] names,
            final PollingManager cacheManager, final List attributeList,
            final AroundInvokeImpl aroundInvoke, final DevSource source, final DeviceLocker locker,
            final ClntIdent clientID) throws DevFailed {
        final boolean fromCache = isFromCache(source);
        final CallType callType = CallType.getFromDevSource(source);
        final AttributeValue_4[] back = new AttributeValue_4[names.length];
        // sort attributes with cache
        final Map cacheAttributes = new HashMap();
        final Map notCacheAttributes = new HashMap();
        for (int i = 0; i < names.length; i++) {
            AttributeImpl att = null;
            try {
                att = getAttribute(names[i], attributeList);
                if (source.equals(DevSource.DEV) && att.isPolled() && att.getPollingPeriod() == 0) {
                    // attribute is polled, so throw exception except
                    back[i] = TangoIDLAttributeUtil.toAttributeValue4Error(
                            names[i],
                            AttrDataFormat.FMT_UNKNOWN,
                            DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_NOT_ALLOWED, ATTRIBUTE + names[i]
                                    + " value is available only by CACHE"));
                } else if (!deviceName.equalsIgnoreCase(ServerManager.getInstance().getAdminDeviceName())
                        && source.equals(DevSource.CACHE) && !att.isPolled()) {
                    // attribute is not polled, so throw exception e'xcept for admin device
                    back[i] = TangoIDLAttributeUtil.toAttributeValue4Error(
                            names[i],
                            AttrDataFormat.FMT_UNKNOWN,
                            DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_NOT_POLLED, ATTRIBUTE + names[i]
                                    + " not polled"));
                } else if (att.isPolled() && fromCache) {
                    cacheAttributes.put(i, att);
                } else {
                    notCacheAttributes.put(i, att);
                }
            } catch (final DevFailed e) {
                back[i] = TangoIDLAttributeUtil.toAttributeValue4Error(names[i], AttrDataFormat.FMT_UNKNOWN, e);
            }
        }

        // get value from cache
        for (final Entry attribute : cacheAttributes.entrySet()) {
            final AttributeImpl att = attribute.getValue();
            final int i = attribute.getKey();
            try {
                LOGGER.debug("read from CACHE {}", att.getName());
                final AttributeValue readValue = cacheManager.getAttributeCacheElement(att);
                if (readValue == null) {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue4Error(names[i], att.getFormat(),
                            DevFailedUtils.newDevFailed("CACHE_ERROR", names[i] + " not available from cache"));
                } else {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue4(att, readValue, att.getWriteValue());
                }
            } catch (final CacheException e) {
                if (e.getCause() instanceof DevFailed) {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue4Error(names[i], AttrDataFormat.FMT_UNKNOWN,
                            (DevFailed) e.getCause());
                }
            }
        }
        // get attributes values
        if (!notCacheAttributes.isEmpty()) {
            final Object lock = locker.getAttributeLock();
            // lock if necessary
            synchronized (lock != null ? lock : new Object()) {
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTES, callType, clientID,
                        names));
                for (final Entry attribute : notCacheAttributes.entrySet()) {
                    final AttributeImpl att = attribute.getValue();
                    final int i = attribute.getKey();
                    LOGGER.debug("read from DEVICE {} ", att.getName());
                    aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTE, callType, clientID,
                            att.getName()));
                    try {
                        synchronized (att) {
                            att.updateValue();
                            back[i] = TangoIDLAttributeUtil.toAttributeValue4(att, att.getReadValue(),
                                    att.getWriteValue());
                        }
                    } catch (final DevFailed e) {
                        back[i] = TangoIDLAttributeUtil.toAttributeValue4Error(names[i], att.getFormat(), e);
                    }
                    aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTE, callType,
                            clientID, att.getName()));
                } // for
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTES, callType, clientID,
                        names));
            } // synchronized
        }

        return back;
    }

    static AttributeValue_3[] getAttributesValues3(final String deviceName, final String[] names,
            final PollingManager cacheManager, final List attributeList,
            final AroundInvokeImpl aroundInvoke, final DevSource source, final DeviceLocker locker,
            final ClntIdent clientID) throws DevFailed {
        final boolean fromCache = isFromCache(source);
        final CallType callType = CallType.getFromDevSource(source);
        final AttributeValue_3[] back = new AttributeValue_3[names.length];
        // sort attributes with cache
        final Map cacheAttributes = new HashMap();
        final Map notCacheAttributes = new HashMap();
        for (int i = 0; i < names.length; i++) {
            AttributeImpl att = null;
            try {
                att = getAttribute(names[i], attributeList);
                if (source.equals(DevSource.DEV) && att.isPolled() && att.getPollingPeriod() == 0) {
                    // attribute is polled, so throw exception except
                    back[i] = TangoIDLAttributeUtil.toAttributeValue3Error(
                            names[i],
                            DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_NOT_ALLOWED, ATTRIBUTE + names[i]
                                    + " value is available only by CACHE"));
                } else if (!deviceName.equalsIgnoreCase(ServerManager.getInstance().getAdminDeviceName())
                        && source.equals(DevSource.CACHE) && !att.isPolled()) {
                    // attribute is not polled, so throw exception e'xcept for admin device
                    back[i] = TangoIDLAttributeUtil.toAttributeValue3Error(
                            names[i],
                            DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_NOT_POLLED, ATTRIBUTE + names[i]
                                    + " not polled"));
                } else if (att.isPolled() && fromCache) {
                    cacheAttributes.put(i, att);
                } else {
                    notCacheAttributes.put(i, att);
                }
            } catch (final DevFailed e) {
                back[i] = TangoIDLAttributeUtil.toAttributeValue3Error(names[i], e);
            }
        }

        // get value from cache
        for (final Entry attribute : cacheAttributes.entrySet()) {
            final AttributeImpl att = attribute.getValue();
            final int i = attribute.getKey();
            try {
                LOGGER.debug("read from CACHE {}", att.getName());
                final AttributeValue readValue = cacheManager.getAttributeCacheElement(att);
                if (readValue == null) {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue3Error(names[i],
                            DevFailedUtils.newDevFailed("CACHE_ERROR", names[i] + " not available from cache"));
                } else {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue3(att, readValue, att.getWriteValue());
                }
            } catch (final CacheException e) {
                if (e.getCause() instanceof DevFailed) {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue3Error(names[i], (DevFailed) e.getCause());
                }
            }
        }
        // get attributes values
        if (!notCacheAttributes.isEmpty()) {
            final Object lock = locker.getAttributeLock();
            // lock if necessary
            synchronized (lock != null ? lock : new Object()) {
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTES, callType, clientID,
                        names));
                for (final Entry attribute : notCacheAttributes.entrySet()) {
                    final AttributeImpl att = attribute.getValue();
                    final int i = attribute.getKey();
                    LOGGER.debug("read from DEVICE {} ", att.getName());
                    aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTE, callType, clientID,
                            att.getName()));
                    try {
                        synchronized (att) {
                            att.updateValue();
                            back[i] = TangoIDLAttributeUtil.toAttributeValue3(att, att.getReadValue(),
                                    att.getWriteValue());
                        }
                    } catch (final DevFailed e) {
                        back[i] = TangoIDLAttributeUtil.toAttributeValue3Error(names[i], e);
                    }
                    aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTE, callType,
                            clientID, att.getName()));
                } // for
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTES, callType, clientID,
                        names));
            } // synchronized
        }
        return back;
    }

    static fr.esrf.Tango.AttributeValue[] getAttributesValues(final String deviceName, final String[] names,
            final PollingManager cacheManager, final List attributeList,
            final AroundInvokeImpl aroundInvoke, final DevSource source, final DeviceLocker locker,
            final ClntIdent clientID) throws DevFailed {
        final boolean fromCache = isFromCache(source);
        final CallType callType = CallType.getFromDevSource(source);

        final fr.esrf.Tango.AttributeValue[] back = new fr.esrf.Tango.AttributeValue[names.length];
        final Map cacheAttributes = new HashMap();
        final Map notCacheAttributes = new HashMap();
        for (int i = 0; i < names.length; i++) {
            final AttributeImpl att = getAttribute(names[i], attributeList);
            if (source.equals(DevSource.DEV) && att.isPolled() && att.getPollingPeriod() == 0) {
                // attribute is polled, so throw exception except
                throw DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_NOT_ALLOWED, ATTRIBUTE + names[i]
                        + " value is available only by CACHE");
            } else if (!deviceName.equalsIgnoreCase(ServerManager.getInstance().getAdminDeviceName())
                    && source.equals(DevSource.CACHE) && !att.isPolled()) {
                // attribute is not polled, so throw exception e'xcept for admin device
                throw DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_NOT_POLLED, ATTRIBUTE + names[i]
                        + " not polled");
            } else if (att.isPolled() && fromCache) {
                cacheAttributes.put(i, att);
            } else {
                notCacheAttributes.put(i, att);
            }

        }

        // get value from cache
        for (final Entry attribute : cacheAttributes.entrySet()) {
            final AttributeImpl att = attribute.getValue();
            final int i = attribute.getKey();
            try {
                LOGGER.debug("read from CACHE {}", att.getName());
                final AttributeValue readValue = cacheManager.getAttributeCacheElement(att);
                if (readValue == null) {
                    throw DevFailedUtils.newDevFailed("CACHE_ERROR", names[i] + " not available from cache");
                } else {
                    back[i] = TangoIDLAttributeUtil.toAttributeValue(att, readValue);
                }
            } catch (final CacheException e) {
                if (e.getCause() instanceof DevFailed) {
                    throw (DevFailed) e.getCause();
                }
            }
        }
        // get attributes values
        if (!notCacheAttributes.isEmpty()) {
            final Object lock = locker.getAttributeLock();
            // lock if necessary
            synchronized (lock != null ? lock : new Object()) {
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTES, callType, clientID,
                        names));
                for (final Entry attribute : notCacheAttributes.entrySet()) {
                    final AttributeImpl att = attribute.getValue();
                    final int i = attribute.getKey();
                    LOGGER.debug("read from DEVICE {} ", att.getName());
                    aroundInvoke.aroundInvoke(new InvocationContext(ContextType.PRE_READ_ATTRIBUTE, callType, clientID,
                            att.getName()));
                    synchronized (att) {
                        att.updateValue();
                        back[i] = TangoIDLAttributeUtil.toAttributeValue(att, att.getReadValue());
                    }
                    aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTE, callType,
                            clientID, att.getName()));
                } // for
                aroundInvoke.aroundInvoke(new InvocationContext(ContextType.POST_READ_ATTRIBUTES, callType, clientID,
                        names));
            } // synchronized
        }
        return back;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy